Updated.
[wine] / dlls / ole32 / antimoniker.c
1 /***************************************************************************************
2  *                            AntiMonikers implementation
3  *
4  *               Copyright 1999  Noomen Hamza
5  ***************************************************************************************/
6
7 #include <assert.h>
8 #include <string.h>
9 #include "winbase.h"
10 #include "winerror.h"
11 #include "wine/unicode.h"
12 #include "wine/obj_base.h"
13 #include "wine/obj_misc.h"
14 #include "wine/obj_storage.h"
15 #include "wine/obj_moniker.h"
16 #include "debugtools.h"
17
18 DEFAULT_DEBUG_CHANNEL(ole);
19
20 /* AntiMoniker data structure */
21 typedef struct AntiMonikerImpl{
22
23     ICOM_VTABLE(IMoniker)*  lpvtbl1;  /* VTable relative to the IMoniker interface.*/
24
25     /* The ROT (RunningObjectTable implementation) uses the IROTData interface to test whether 
26      * two monikers are equal. That's whay IROTData interface is implemented by monikers.
27      */
28     ICOM_VTABLE(IROTData)*  lpvtbl2;  /* VTable relative to the IROTData interface.*/
29
30     ULONG ref; /* reference counter for this object */
31
32 } AntiMonikerImpl;
33
34 /********************************************************************************/
35 /* AntiMoniker prototype functions :                                            */
36
37 /* IUnknown prototype functions */
38 static HRESULT WINAPI AntiMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject);
39 static ULONG   WINAPI AntiMonikerImpl_AddRef(IMoniker* iface);
40 static ULONG   WINAPI AntiMonikerImpl_Release(IMoniker* iface);
41
42 /* IPersist prototype functions */
43 static HRESULT WINAPI AntiMonikerImpl_GetClassID(IMoniker* iface, CLSID *pClassID);
44
45 /* IPersistStream prototype functions */
46 static HRESULT WINAPI AntiMonikerImpl_IsDirty(IMoniker* iface);
47 static HRESULT WINAPI AntiMonikerImpl_Load(IMoniker* iface, IStream* pStm);
48 static HRESULT WINAPI AntiMonikerImpl_Save(IMoniker* iface, IStream* pStm, BOOL fClearDirty);
49 static HRESULT WINAPI AntiMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize);
50
51 /* IMoniker prototype functions */
52 static HRESULT WINAPI AntiMonikerImpl_BindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
53 static HRESULT WINAPI AntiMonikerImpl_BindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult);
54 static HRESULT WINAPI AntiMonikerImpl_Reduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced);
55 static HRESULT WINAPI AntiMonikerImpl_ComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite);
56 static HRESULT WINAPI AntiMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker);
57 static HRESULT WINAPI AntiMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker);
58 static HRESULT WINAPI AntiMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash);
59 static HRESULT WINAPI AntiMonikerImpl_IsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning);
60 static HRESULT WINAPI AntiMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pAntiTime);
61 static HRESULT WINAPI AntiMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk);
62 static HRESULT WINAPI AntiMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix);
63 static HRESULT WINAPI AntiMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath);
64 static HRESULT WINAPI AntiMonikerImpl_GetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName);
65 static HRESULT WINAPI AntiMonikerImpl_ParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut);
66 static HRESULT WINAPI AntiMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys);
67
68 /********************************************************************************/
69 /* IROTData prototype functions                                                 */
70
71 /* IUnknown prototype functions */
72 static HRESULT WINAPI AntiMonikerROTDataImpl_QueryInterface(IROTData* iface,REFIID riid,VOID** ppvObject);
73 static ULONG   WINAPI AntiMonikerROTDataImpl_AddRef(IROTData* iface);
74 static ULONG   WINAPI AntiMonikerROTDataImpl_Release(IROTData* iface);
75
76 /* IROTData prototype function */
77 static HRESULT WINAPI AntiMonikerROTDataImpl_GetComparaisonData(IROTData* iface,BYTE* pbData,ULONG cbMax,ULONG* pcbData);
78
79 /* Local function used by AntiMoniker implementation */
80 HRESULT WINAPI AntiMonikerImpl_Construct(AntiMonikerImpl* iface);
81 HRESULT WINAPI AntiMonikerImpl_Destroy(AntiMonikerImpl* iface);
82
83 /********************************************************************************/
84 /* Virtual function table for the AntiMonikerImpl class which  include IPersist,*/
85 /* IPersistStream and IMoniker functions.                                       */
86 static ICOM_VTABLE(IMoniker) VT_AntiMonikerImpl =
87 {
88     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
89     AntiMonikerImpl_QueryInterface,
90     AntiMonikerImpl_AddRef,
91     AntiMonikerImpl_Release,
92     AntiMonikerImpl_GetClassID,
93     AntiMonikerImpl_IsDirty,
94     AntiMonikerImpl_Load,
95     AntiMonikerImpl_Save,
96     AntiMonikerImpl_GetSizeMax,
97     AntiMonikerImpl_BindToObject,
98     AntiMonikerImpl_BindToStorage,
99     AntiMonikerImpl_Reduce,
100     AntiMonikerImpl_ComposeWith,
101     AntiMonikerImpl_Enum,
102     AntiMonikerImpl_IsEqual,
103     AntiMonikerImpl_Hash,
104     AntiMonikerImpl_IsRunning,
105     AntiMonikerImpl_GetTimeOfLastChange,
106     AntiMonikerImpl_Inverse,
107     AntiMonikerImpl_CommonPrefixWith,
108     AntiMonikerImpl_RelativePathTo,
109     AntiMonikerImpl_GetDisplayName,
110     AntiMonikerImpl_ParseDisplayName,
111     AntiMonikerImpl_IsSystemMoniker
112 };
113
114 /********************************************************************************/
115 /* Virtual function table for the IROTData class.                               */
116 static ICOM_VTABLE(IROTData) VT_ROTDataImpl =
117 {
118     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
119     AntiMonikerROTDataImpl_QueryInterface,
120     AntiMonikerROTDataImpl_AddRef,
121     AntiMonikerROTDataImpl_Release,
122     AntiMonikerROTDataImpl_GetComparaisonData
123 };
124
125 /*******************************************************************************
126  *        AntiMoniker_QueryInterface
127  *******************************************************************************/
128 HRESULT WINAPI AntiMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
129 {
130     ICOM_THIS(AntiMonikerImpl,iface);
131   
132   TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
133
134   /* Perform a sanity check on the parameters.*/
135     if ( (This==0) || (ppvObject==0) )
136         return E_INVALIDARG;
137   
138   /* Initialize the return parameter */
139   *ppvObject = 0;
140
141   /* Compare the riid with the interface IDs implemented by this object.*/
142   if (IsEqualIID(&IID_IUnknown, riid) ||
143       IsEqualIID(&IID_IPersist, riid) ||
144       IsEqualIID(&IID_IPersistStream, riid) ||
145       IsEqualIID(&IID_IMoniker, riid)
146      )
147       *ppvObject = iface;
148     else if (IsEqualIID(&IID_IROTData, riid))
149         *ppvObject = (IROTData*)&(This->lpvtbl2);
150
151   /* Check that we obtained an interface.*/
152     if ((*ppvObject)==0)
153         return E_NOINTERFACE;
154   
155    /* Query Interface always increases the reference count by one when it is successful */
156   AntiMonikerImpl_AddRef(iface);
157
158   return S_OK;
159 }
160
161 /******************************************************************************
162  *        AntiMoniker_AddRef
163  ******************************************************************************/
164 ULONG WINAPI AntiMonikerImpl_AddRef(IMoniker* iface)
165 {
166     ICOM_THIS(AntiMonikerImpl,iface);
167
168     TRACE("(%p)\n",This);
169
170     return ++(This->ref);
171 }
172
173 /******************************************************************************
174  *        AntiMoniker_Release
175  ******************************************************************************/
176 ULONG WINAPI AntiMonikerImpl_Release(IMoniker* iface)
177 {
178     ICOM_THIS(AntiMonikerImpl,iface);
179
180     TRACE("(%p)\n",This);
181
182     This->ref--;
183
184     /* destroy the object if there's no more reference on it */
185     if (This->ref==0){
186
187         AntiMonikerImpl_Destroy(This);
188
189         return 0;
190     }
191     return This->ref;;
192 }
193
194 /******************************************************************************
195  *        AntiMoniker_GetClassID
196  ******************************************************************************/
197 HRESULT WINAPI AntiMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
198 {
199     TRACE("(%p,%p),stub!\n",iface,pClassID);
200
201     if (pClassID==NULL)
202         return E_POINTER;
203             
204     *pClassID = CLSID_AntiMoniker;
205         
206     return S_OK;
207 }
208
209 /******************************************************************************
210  *        AntiMoniker_IsDirty
211  ******************************************************************************/
212 HRESULT WINAPI AntiMonikerImpl_IsDirty(IMoniker* iface)
213 {
214     /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
215        method in the OLE-provided moniker interfaces always return S_FALSE because
216        their internal state never changes. */
217
218     TRACE("(%p)\n",iface);
219
220     return S_FALSE;
221 }
222
223 /******************************************************************************
224  *        AntiMoniker_Load
225  ******************************************************************************/
226 HRESULT WINAPI AntiMonikerImpl_Load(IMoniker* iface,IStream* pStm)
227 {
228     DWORD constant=1,dwbuffer;
229     HRESULT res;
230
231     /* data read by this function is only a DWORD constant (must be 1) ! */
232     res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),NULL);
233
234     if (SUCCEEDED(res)&& dwbuffer!=constant)
235         return E_FAIL;
236
237     return res;
238 }
239
240 /******************************************************************************
241  *        AntiMoniker_Save
242  ******************************************************************************/
243 HRESULT WINAPI AntiMonikerImpl_Save(IMoniker* iface,IStream* pStm,BOOL fClearDirty)
244 {
245     DWORD constant=1;
246     HRESULT res;
247     
248     /* data writen by this function is only a DWORD constant seted to 1 ! */
249     res=IStream_Write(pStm,&constant,sizeof(constant),NULL);
250
251     return res;
252 }
253
254 /******************************************************************************
255  *        AntiMoniker_GetSizeMax
256  ******************************************************************************/
257 HRESULT WINAPI AntiMonikerImpl_GetSizeMax(IMoniker* iface,
258                                           ULARGE_INTEGER* pcbSize)/* Pointer to size of stream needed to save object */
259 {
260     TRACE("(%p,%p)\n",iface,pcbSize);
261
262     if (pcbSize!=NULL)
263         return E_POINTER;
264
265     /* for more details see AntiMonikerImpl_Save coments */
266     
267     /* Normaly the sizemax must be the  size of DWORD ! but I tested this function it ususlly return 16 bytes */
268     /* more than the number of bytes used by AntiMoniker::Save function */
269     pcbSize->s.LowPart =  sizeof(DWORD)+16;
270
271     pcbSize->s.HighPart=0;
272
273     return S_OK;
274 }
275
276 /******************************************************************************
277  *         AntiMoniker_Construct (local function)
278  *******************************************************************************/
279 HRESULT WINAPI AntiMonikerImpl_Construct(AntiMonikerImpl* This)
280 {
281
282     TRACE("(%p)\n",This);
283
284     /* Initialize the virtual fgunction table. */
285     This->lpvtbl1      = &VT_AntiMonikerImpl;
286     This->lpvtbl2      = &VT_ROTDataImpl;
287     This->ref          = 0;
288
289     return S_OK;
290 }
291
292 /******************************************************************************
293  *        AntiMoniker_Destroy (local function)
294  *******************************************************************************/
295 HRESULT WINAPI AntiMonikerImpl_Destroy(AntiMonikerImpl* This)
296 {
297     TRACE("(%p)\n",This);
298
299     return HeapFree(GetProcessHeap(),0,This);
300 }
301
302 /******************************************************************************
303  *                  AntiMoniker_BindToObject
304  ******************************************************************************/
305 HRESULT WINAPI AntiMonikerImpl_BindToObject(IMoniker* iface,
306                                             IBindCtx* pbc,
307                                             IMoniker* pmkToLeft,
308                                             REFIID riid,
309                                             VOID** ppvResult)
310 {
311     TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
312     return E_NOTIMPL;
313 }
314
315 /******************************************************************************
316  *        AntiMoniker_BindToStorage
317  ******************************************************************************/
318 HRESULT WINAPI AntiMonikerImpl_BindToStorage(IMoniker* iface,
319                                              IBindCtx* pbc,
320                                              IMoniker* pmkToLeft,
321                                              REFIID riid,
322                                              VOID** ppvResult)
323 {
324     TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
325     return E_NOTIMPL;
326 }
327
328 /******************************************************************************
329  *        AntiMoniker_Reduce
330  ******************************************************************************/
331 HRESULT WINAPI AntiMonikerImpl_Reduce(IMoniker* iface,
332                                       IBindCtx* pbc,
333                                       DWORD dwReduceHowFar,
334                                       IMoniker** ppmkToLeft,
335                                       IMoniker** ppmkReduced)
336 {
337     TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
338
339     if (ppmkReduced==NULL)
340         return E_POINTER;
341
342     AntiMonikerImpl_AddRef(iface);
343
344     *ppmkReduced=iface;
345     
346     return MK_S_REDUCED_TO_SELF;
347 }
348 /******************************************************************************
349  *        AntiMoniker_ComposeWith
350  ******************************************************************************/
351 HRESULT WINAPI AntiMonikerImpl_ComposeWith(IMoniker* iface,
352                                            IMoniker* pmkRight,
353                                            BOOL fOnlyIfNotGeneric,
354                                            IMoniker** ppmkComposite)
355 {
356
357     TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
358
359     if ((ppmkComposite==NULL)||(pmkRight==NULL))
360         return E_POINTER;
361
362     *ppmkComposite=0;
363     
364     if (fOnlyIfNotGeneric)
365         return MK_E_NEEDGENERIC;
366     else
367         return CreateGenericComposite(iface,pmkRight,ppmkComposite);
368 }
369
370 /******************************************************************************
371  *        AntiMoniker_Enum
372  ******************************************************************************/
373 HRESULT WINAPI AntiMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
374 {
375     TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
376
377     if (ppenumMoniker == NULL)
378         return E_POINTER;
379     
380     *ppenumMoniker = NULL;
381
382     return S_OK;
383 }
384
385 /******************************************************************************
386  *        AntiMoniker_IsEqual
387  ******************************************************************************/
388 HRESULT WINAPI AntiMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
389 {
390     DWORD mkSys;
391     
392     TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
393
394     if (pmkOtherMoniker==NULL)
395         return S_FALSE;
396     
397     IMoniker_IsSystemMoniker(pmkOtherMoniker,&mkSys);
398
399     if (mkSys==MKSYS_ANTIMONIKER)
400         return S_OK;
401     else
402         return S_FALSE;
403 }
404
405 /******************************************************************************
406  *        AntiMoniker_Hash
407  ******************************************************************************/
408 HRESULT WINAPI AntiMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
409 {
410     if (pdwHash==NULL)
411         return E_POINTER;
412
413     *pdwHash=0;
414
415     return S_OK;
416 }
417
418 /******************************************************************************
419  *        AntiMoniker_IsRunning
420  ******************************************************************************/
421 HRESULT WINAPI AntiMonikerImpl_IsRunning(IMoniker* iface,
422                                          IBindCtx* pbc,
423                                          IMoniker* pmkToLeft,
424                                          IMoniker* pmkNewlyRunning)
425 {
426     IRunningObjectTable* rot;
427     HRESULT res;
428
429     TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
430
431     if (pbc==NULL)
432         return E_INVALIDARG;
433
434     res=IBindCtx_GetRunningObjectTable(pbc,&rot);
435
436     if (FAILED(res))
437     return res;
438
439     res = IRunningObjectTable_IsRunning(rot,iface);
440
441     IRunningObjectTable_Release(rot);
442
443     return res;
444 }
445
446 /******************************************************************************
447  *        AntiMoniker_GetTimeOfLastChange
448  ******************************************************************************/
449 HRESULT WINAPI AntiMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
450                                                    IBindCtx* pbc,
451                                                    IMoniker* pmkToLeft,
452                                                    FILETIME* pAntiTime)
453 {
454     TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pAntiTime);
455     return E_NOTIMPL;
456 }
457
458 /******************************************************************************
459  *        AntiMoniker_Inverse
460  ******************************************************************************/
461 HRESULT WINAPI AntiMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
462 {
463     TRACE("(%p,%p)\n",iface,ppmk);
464
465     if (ppmk==NULL)
466         return E_POINTER;
467
468     *ppmk=0;
469
470     return MK_E_NOINVERSE;
471 }
472
473 /******************************************************************************
474  *        AntiMoniker_CommonPrefixWith
475  ******************************************************************************/
476 HRESULT WINAPI AntiMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
477 {
478     DWORD mkSys;
479     
480     IMoniker_IsSystemMoniker(pmkOther,&mkSys);
481
482     if(mkSys==MKSYS_ITEMMONIKER){
483
484         IMoniker_AddRef(iface);
485
486         *ppmkPrefix=iface;
487
488         IMoniker_AddRef(iface);
489         
490         return MK_S_US;
491     }
492     else
493         return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix);
494 }
495
496 /******************************************************************************
497  *        AntiMoniker_RelativePathTo
498  ******************************************************************************/
499 HRESULT WINAPI AntiMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
500 {
501     TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);
502
503     if (ppmkRelPath==NULL)
504         return E_POINTER;
505
506     IMoniker_AddRef(pmOther);
507
508     *ppmkRelPath=pmOther;
509
510     return MK_S_HIM;
511 }
512
513 /******************************************************************************
514  *        AntiMoniker_GetDisplayName
515  ******************************************************************************/
516 HRESULT WINAPI AntiMonikerImpl_GetDisplayName(IMoniker* iface,
517                                               IBindCtx* pbc,
518                                               IMoniker* pmkToLeft,
519                                               LPOLESTR *ppszDisplayName)
520 {
521     WCHAR back[]={'\\','.','.',0};
522     
523     TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
524
525     if (ppszDisplayName==NULL)
526         return E_POINTER;
527
528     if (pmkToLeft!=NULL){
529         FIXME("() pmkToLeft!=NULL not implemented \n");
530         return E_NOTIMPL;
531     }
532
533     *ppszDisplayName=CoTaskMemAlloc(sizeof(back));
534
535     if (*ppszDisplayName==NULL)
536         return E_OUTOFMEMORY;
537
538     strcpyW(*ppszDisplayName,back);
539     
540     return S_OK;
541 }
542
543 /******************************************************************************
544  *        AntiMoniker_ParseDisplayName
545  ******************************************************************************/
546 HRESULT WINAPI AntiMonikerImpl_ParseDisplayName(IMoniker* iface,
547                                                 IBindCtx* pbc,
548                                                 IMoniker* pmkToLeft,
549                                                 LPOLESTR pszDisplayName,
550                                                 ULONG* pchEaten,
551                                                 IMoniker** ppmkOut)
552 {
553     TRACE("(%p,%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);
554     return E_NOTIMPL;
555 }
556
557 /******************************************************************************
558  *        AntiMoniker_IsSystemMonker
559  ******************************************************************************/
560 HRESULT WINAPI AntiMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
561 {
562     TRACE("(%p,%p)\n",iface,pwdMksys);
563
564     if (!pwdMksys)
565         return E_POINTER;
566     
567     (*pwdMksys)=MKSYS_ANTIMONIKER;
568
569     return S_OK;
570 }
571
572 /*******************************************************************************
573  *        AntiMonikerIROTData_QueryInterface
574  *******************************************************************************/
575 HRESULT WINAPI AntiMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
576 {
577
578     ICOM_THIS_From_IROTData(IMoniker, iface);
579
580     TRACE("(%p,%p,%p)\n",iface,riid,ppvObject);
581
582     return AntiMonikerImpl_QueryInterface(This, riid, ppvObject);
583 }
584
585 /***********************************************************************
586  *        AntiMonikerIROTData_AddRef
587  */
588 ULONG   WINAPI AntiMonikerROTDataImpl_AddRef(IROTData *iface)
589 {
590     ICOM_THIS_From_IROTData(IMoniker, iface);
591
592     TRACE("(%p)\n",iface);
593
594     return AntiMonikerImpl_AddRef(This);
595 }
596
597 /***********************************************************************
598  *        AntiMonikerIROTData_Release
599  */
600 ULONG   WINAPI AntiMonikerROTDataImpl_Release(IROTData* iface)
601 {
602     ICOM_THIS_From_IROTData(IMoniker, iface);
603     
604     TRACE("(%p)\n",iface);
605
606     return AntiMonikerImpl_Release(This);
607 }
608
609 /******************************************************************************
610  *        AntiMonikerIROTData_GetComparaisonData
611  ******************************************************************************/
612 HRESULT WINAPI AntiMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
613                                                          BYTE* pbData,
614                                                          ULONG cbMax,
615                                                          ULONG* pcbData)
616 {
617     FIXME("(),stub!\n");
618     return E_NOTIMPL;
619 }
620
621 /******************************************************************************
622  *        CreateAntiMoniker     [OLE.55]
623  ******************************************************************************/
624 HRESULT WINAPI CreateAntiMoniker(LPMONIKER * ppmk)
625 {
626     AntiMonikerImpl* newAntiMoniker = 0;
627     HRESULT        hr = S_OK;
628     IID riid=IID_IMoniker;
629     
630     TRACE("(%p)\n",ppmk);
631
632     newAntiMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(AntiMonikerImpl));
633
634     if (newAntiMoniker == 0)
635         return STG_E_INSUFFICIENTMEMORY;
636
637     hr = AntiMonikerImpl_Construct(newAntiMoniker);
638
639     if (FAILED(hr)){
640
641         HeapFree(GetProcessHeap(),0,newAntiMoniker);
642         return hr;
643     }
644
645     hr = AntiMonikerImpl_QueryInterface((IMoniker*)newAntiMoniker,&riid,(void**)ppmk);
646
647     return hr;
648 }