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