ddraw/tests: Add another invalid arguments test for surface QI.
[wine.git] / dlls / ole32 / antimoniker.c
blobf7912fad7895ce66cf34a298b9ff8d29c01056b0
1 /*
2 * AntiMonikers implementation
4 * Copyright 1999 Noomen Hamza
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.
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.
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
21 #include <assert.h>
22 #include <stdarg.h>
23 #include <string.h>
25 #define COBJMACROS
26 #define NONAMELESSUNION
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winerror.h"
31 #include "objbase.h"
32 #include "wine/debug.h"
33 #include "moniker.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(ole);
37 /* AntiMoniker data structure */
38 typedef struct AntiMonikerImpl{
39 IMoniker IMoniker_iface;
40 IROTData IROTData_iface;
41 LONG ref;
42 IUnknown *pMarshal; /* custom marshaler */
43 } AntiMonikerImpl;
45 static inline AntiMonikerImpl *impl_from_IMoniker(IMoniker *iface)
47 return CONTAINING_RECORD(iface, AntiMonikerImpl, IMoniker_iface);
50 static inline AntiMonikerImpl *impl_from_IROTData(IROTData *iface)
52 return CONTAINING_RECORD(iface, AntiMonikerImpl, IROTData_iface);
56 /*******************************************************************************
57 * AntiMoniker_QueryInterface
58 *******************************************************************************/
59 static HRESULT WINAPI
60 AntiMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
62 AntiMonikerImpl *This = impl_from_IMoniker(iface);
64 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
66 /* Perform a sanity check on the parameters.*/
67 if ( ppvObject==0 )
68 return E_INVALIDARG;
70 /* Initialize the return parameter */
71 *ppvObject = 0;
73 /* Compare the riid with the interface IDs implemented by this object.*/
74 if (IsEqualIID(&IID_IUnknown, riid) ||
75 IsEqualIID(&IID_IPersist, riid) ||
76 IsEqualIID(&IID_IPersistStream, 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))
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);
91 /* Check that we obtained an interface.*/
92 if ((*ppvObject)==0)
93 return E_NOINTERFACE;
95 /* always increase the reference count by one when it is successful */
96 IMoniker_AddRef(iface);
98 return S_OK;
101 /******************************************************************************
102 * AntiMoniker_AddRef
103 ******************************************************************************/
104 static ULONG WINAPI
105 AntiMonikerImpl_AddRef(IMoniker* iface)
107 AntiMonikerImpl *This = impl_from_IMoniker(iface);
109 TRACE("(%p)\n",This);
111 return InterlockedIncrement(&This->ref);
114 /******************************************************************************
115 * AntiMoniker_Release
116 ******************************************************************************/
117 static ULONG WINAPI
118 AntiMonikerImpl_Release(IMoniker* iface)
120 AntiMonikerImpl *This = impl_from_IMoniker(iface);
121 ULONG ref;
123 TRACE("(%p)\n",This);
125 ref = InterlockedDecrement(&This->ref);
127 /* destroy the object if there are no more references to it */
128 if (ref == 0)
130 if (This->pMarshal) IUnknown_Release(This->pMarshal);
131 HeapFree(GetProcessHeap(),0,This);
134 return ref;
137 /******************************************************************************
138 * AntiMoniker_GetClassID
139 ******************************************************************************/
140 static HRESULT WINAPI
141 AntiMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
143 TRACE("(%p,%p)\n",iface,pClassID);
145 if (pClassID==NULL)
146 return E_POINTER;
148 *pClassID = CLSID_AntiMoniker;
150 return S_OK;
153 /******************************************************************************
154 * AntiMoniker_IsDirty
155 ******************************************************************************/
156 static HRESULT WINAPI
157 AntiMonikerImpl_IsDirty(IMoniker* iface)
159 /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
160 method in the OLE-provided moniker interfaces always return S_FALSE because
161 their internal state never changes. */
163 TRACE("(%p)\n",iface);
165 return S_FALSE;
168 /******************************************************************************
169 * AntiMoniker_Load
170 ******************************************************************************/
171 static HRESULT WINAPI
172 AntiMonikerImpl_Load(IMoniker* iface,IStream* pStm)
174 DWORD constant=1,dwbuffer;
175 HRESULT res;
177 /* data read by this function is only a DWORD constant (must be 1) ! */
178 res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),NULL);
180 if (SUCCEEDED(res)&& dwbuffer!=constant)
181 return E_FAIL;
183 return res;
186 /******************************************************************************
187 * AntiMoniker_Save
188 ******************************************************************************/
189 static HRESULT WINAPI
190 AntiMonikerImpl_Save(IMoniker* iface,IStream* pStm,BOOL fClearDirty)
192 static const DWORD constant = 1;
193 /* data written by this function is only a DWORD constant set to 1 ! */
194 return IStream_Write(pStm,&constant,sizeof(constant),NULL);
197 /******************************************************************************
198 * AntiMoniker_GetSizeMax
200 * PARAMS
201 * pcbSize [out] Pointer to size of stream needed to save object
202 ******************************************************************************/
203 static HRESULT WINAPI
204 AntiMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
206 TRACE("(%p,%p)\n",iface,pcbSize);
208 if (!pcbSize)
209 return E_POINTER;
211 /* for more details see AntiMonikerImpl_Save comments */
214 * Normally the sizemax must be sizeof DWORD, but
215 * I tested this function it usually return 16 bytes
216 * more than the number of bytes used by AntiMoniker::Save function
218 pcbSize->u.LowPart = sizeof(DWORD)+16;
220 pcbSize->u.HighPart=0;
222 return S_OK;
225 /******************************************************************************
226 * AntiMoniker_BindToObject
227 ******************************************************************************/
228 static HRESULT WINAPI
229 AntiMonikerImpl_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
230 REFIID riid, VOID** ppvResult)
232 TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
233 return E_NOTIMPL;
236 /******************************************************************************
237 * AntiMoniker_BindToStorage
238 ******************************************************************************/
239 static HRESULT WINAPI
240 AntiMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
241 REFIID riid, VOID** ppvResult)
243 TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
244 return E_NOTIMPL;
247 /******************************************************************************
248 * AntiMoniker_Reduce
249 ******************************************************************************/
250 static HRESULT WINAPI
251 AntiMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
252 IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
254 TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
256 if (ppmkReduced==NULL)
257 return E_POINTER;
259 AntiMonikerImpl_AddRef(iface);
261 *ppmkReduced=iface;
263 return MK_S_REDUCED_TO_SELF;
265 /******************************************************************************
266 * AntiMoniker_ComposeWith
267 ******************************************************************************/
268 static HRESULT WINAPI
269 AntiMonikerImpl_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
270 BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
273 TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
275 if ((ppmkComposite==NULL)||(pmkRight==NULL))
276 return E_POINTER;
278 *ppmkComposite=0;
280 if (fOnlyIfNotGeneric)
281 return MK_E_NEEDGENERIC;
282 else
283 return CreateGenericComposite(iface,pmkRight,ppmkComposite);
286 /******************************************************************************
287 * AntiMoniker_Enum
288 ******************************************************************************/
289 static HRESULT WINAPI
290 AntiMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
292 TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
294 if (ppenumMoniker == NULL)
295 return E_POINTER;
297 *ppenumMoniker = NULL;
299 return S_OK;
302 /******************************************************************************
303 * AntiMoniker_IsEqual
304 ******************************************************************************/
305 static HRESULT WINAPI
306 AntiMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
308 DWORD mkSys;
310 TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
312 if (pmkOtherMoniker==NULL)
313 return S_FALSE;
315 IMoniker_IsSystemMoniker(pmkOtherMoniker,&mkSys);
317 if (mkSys==MKSYS_ANTIMONIKER)
318 return S_OK;
319 else
320 return S_FALSE;
323 /******************************************************************************
324 * AntiMoniker_Hash
325 ******************************************************************************/
326 static HRESULT WINAPI AntiMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
328 if (pdwHash==NULL)
329 return E_POINTER;
331 *pdwHash = 0x80000001;
333 return S_OK;
336 /******************************************************************************
337 * AntiMoniker_IsRunning
338 ******************************************************************************/
339 static HRESULT WINAPI
340 AntiMonikerImpl_IsRunning(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
341 IMoniker* pmkNewlyRunning)
343 IRunningObjectTable* rot;
344 HRESULT res;
346 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
348 if (pbc==NULL)
349 return E_INVALIDARG;
351 res=IBindCtx_GetRunningObjectTable(pbc,&rot);
353 if (FAILED(res))
354 return res;
356 res = IRunningObjectTable_IsRunning(rot,iface);
358 IRunningObjectTable_Release(rot);
360 return res;
363 /******************************************************************************
364 * AntiMoniker_GetTimeOfLastChange
365 ******************************************************************************/
366 static HRESULT WINAPI AntiMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
367 IBindCtx* pbc,
368 IMoniker* pmkToLeft,
369 FILETIME* pAntiTime)
371 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pAntiTime);
372 return E_NOTIMPL;
375 /******************************************************************************
376 * AntiMoniker_Inverse
377 ******************************************************************************/
378 static HRESULT WINAPI
379 AntiMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
381 TRACE("(%p,%p)\n",iface,ppmk);
383 if (ppmk==NULL)
384 return E_POINTER;
386 *ppmk=0;
388 return MK_E_NOINVERSE;
391 /******************************************************************************
392 * AntiMoniker_CommonPrefixWith
393 ******************************************************************************/
394 static HRESULT WINAPI
395 AntiMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
397 DWORD mkSys;
399 IMoniker_IsSystemMoniker(pmkOther,&mkSys);
401 if(mkSys==MKSYS_ANTIMONIKER){
403 IMoniker_AddRef(iface);
405 *ppmkPrefix=iface;
407 IMoniker_AddRef(iface);
409 return MK_S_US;
411 else
412 return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix);
415 /******************************************************************************
416 * AntiMoniker_RelativePathTo
417 ******************************************************************************/
418 static HRESULT WINAPI
419 AntiMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
421 TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);
423 if (ppmkRelPath==NULL)
424 return E_POINTER;
426 IMoniker_AddRef(pmOther);
428 *ppmkRelPath=pmOther;
430 return MK_S_HIM;
433 /******************************************************************************
434 * AntiMoniker_GetDisplayName
435 ******************************************************************************/
436 static HRESULT WINAPI
437 AntiMonikerImpl_GetDisplayName(IMoniker* iface, IBindCtx* pbc,
438 IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
440 static const WCHAR back[]={'\\','.','.',0};
442 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);
444 if (ppszDisplayName==NULL)
445 return E_POINTER;
447 if (pmkToLeft!=NULL){
448 FIXME("() pmkToLeft!=NULL not implemented\n");
449 return E_NOTIMPL;
452 *ppszDisplayName=CoTaskMemAlloc(sizeof(back));
454 if (*ppszDisplayName==NULL)
455 return E_OUTOFMEMORY;
457 lstrcpyW(*ppszDisplayName,back);
459 return S_OK;
462 /******************************************************************************
463 * AntiMoniker_ParseDisplayName
464 ******************************************************************************/
465 static HRESULT WINAPI
466 AntiMonikerImpl_ParseDisplayName(IMoniker* iface, IBindCtx* pbc,
467 IMoniker* pmkToLeft, LPOLESTR pszDisplayName,
468 ULONG* pchEaten, IMoniker** ppmkOut)
470 TRACE("(%p,%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);
471 return E_NOTIMPL;
474 /******************************************************************************
475 * AntiMoniker_IsSystemMoniker
476 ******************************************************************************/
477 static HRESULT WINAPI
478 AntiMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
480 TRACE("(%p,%p)\n",iface,pwdMksys);
482 if (!pwdMksys)
483 return E_POINTER;
485 (*pwdMksys)=MKSYS_ANTIMONIKER;
487 return S_OK;
490 /*******************************************************************************
491 * AntiMonikerIROTData_QueryInterface
492 *******************************************************************************/
493 static HRESULT WINAPI
494 AntiMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
496 AntiMonikerImpl *This = impl_from_IROTData(iface);
498 TRACE("(%p,%s,%p)\n",iface,debugstr_guid(riid),ppvObject);
500 return AntiMonikerImpl_QueryInterface(&This->IMoniker_iface, riid, ppvObject);
503 /***********************************************************************
504 * AntiMonikerIROTData_AddRef
506 static ULONG WINAPI AntiMonikerROTDataImpl_AddRef(IROTData *iface)
508 AntiMonikerImpl *This = impl_from_IROTData(iface);
510 TRACE("(%p)\n",iface);
512 return AntiMonikerImpl_AddRef(&This->IMoniker_iface);
515 /***********************************************************************
516 * AntiMonikerIROTData_Release
518 static ULONG WINAPI AntiMonikerROTDataImpl_Release(IROTData* iface)
520 AntiMonikerImpl *This = impl_from_IROTData(iface);
522 TRACE("(%p)\n",iface);
524 return AntiMonikerImpl_Release(&This->IMoniker_iface);
527 /******************************************************************************
528 * AntiMonikerIROTData_GetComparisonData
529 ******************************************************************************/
530 static HRESULT WINAPI
531 AntiMonikerROTDataImpl_GetComparisonData(IROTData* iface, BYTE* pbData,
532 ULONG cbMax, ULONG* pcbData)
534 DWORD constant = 1;
536 TRACE("(%p, %u, %p)\n", pbData, cbMax, pcbData);
538 *pcbData = sizeof(CLSID) + sizeof(DWORD);
539 if (cbMax < *pcbData)
540 return E_OUTOFMEMORY;
542 memcpy(pbData, &CLSID_AntiMoniker, sizeof(CLSID));
543 memcpy(pbData+sizeof(CLSID), &constant, sizeof(DWORD));
545 return S_OK;
548 /********************************************************************************/
549 /* Virtual function table for the AntiMonikerImpl class which include IPersist,*/
550 /* IPersistStream and IMoniker functions. */
551 static const IMonikerVtbl VT_AntiMonikerImpl =
553 AntiMonikerImpl_QueryInterface,
554 AntiMonikerImpl_AddRef,
555 AntiMonikerImpl_Release,
556 AntiMonikerImpl_GetClassID,
557 AntiMonikerImpl_IsDirty,
558 AntiMonikerImpl_Load,
559 AntiMonikerImpl_Save,
560 AntiMonikerImpl_GetSizeMax,
561 AntiMonikerImpl_BindToObject,
562 AntiMonikerImpl_BindToStorage,
563 AntiMonikerImpl_Reduce,
564 AntiMonikerImpl_ComposeWith,
565 AntiMonikerImpl_Enum,
566 AntiMonikerImpl_IsEqual,
567 AntiMonikerImpl_Hash,
568 AntiMonikerImpl_IsRunning,
569 AntiMonikerImpl_GetTimeOfLastChange,
570 AntiMonikerImpl_Inverse,
571 AntiMonikerImpl_CommonPrefixWith,
572 AntiMonikerImpl_RelativePathTo,
573 AntiMonikerImpl_GetDisplayName,
574 AntiMonikerImpl_ParseDisplayName,
575 AntiMonikerImpl_IsSystemMoniker
578 /********************************************************************************/
579 /* Virtual function table for the IROTData class. */
580 static const IROTDataVtbl VT_ROTDataImpl =
582 AntiMonikerROTDataImpl_QueryInterface,
583 AntiMonikerROTDataImpl_AddRef,
584 AntiMonikerROTDataImpl_Release,
585 AntiMonikerROTDataImpl_GetComparisonData
588 /******************************************************************************
589 * AntiMoniker_Construct (local function)
590 *******************************************************************************/
591 static HRESULT AntiMonikerImpl_Construct(AntiMonikerImpl* This)
594 TRACE("(%p)\n",This);
596 /* Initialize the virtual function table. */
597 This->IMoniker_iface.lpVtbl = &VT_AntiMonikerImpl;
598 This->IROTData_iface.lpVtbl = &VT_ROTDataImpl;
599 This->ref = 0;
600 This->pMarshal = NULL;
602 return S_OK;
605 /******************************************************************************
606 * CreateAntiMoniker [OLE32.@]
607 ******************************************************************************/
608 HRESULT WINAPI CreateAntiMoniker(IMoniker **ppmk)
610 AntiMonikerImpl* newAntiMoniker;
611 HRESULT hr;
613 TRACE("(%p)\n",ppmk);
615 newAntiMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(AntiMonikerImpl));
617 if (newAntiMoniker == 0)
618 return STG_E_INSUFFICIENTMEMORY;
620 hr = AntiMonikerImpl_Construct(newAntiMoniker);
621 if (FAILED(hr))
623 HeapFree(GetProcessHeap(),0,newAntiMoniker);
624 return hr;
627 return AntiMonikerImpl_QueryInterface(&newAntiMoniker->IMoniker_iface, &IID_IMoniker,
628 (void**)ppmk);
631 HRESULT WINAPI AntiMoniker_CreateInstance(IClassFactory *iface,
632 IUnknown *pUnk, REFIID riid, void **ppv)
634 IMoniker *pMoniker;
635 HRESULT hr;
637 TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
639 *ppv = NULL;
641 if (pUnk)
642 return CLASS_E_NOAGGREGATION;
644 hr = CreateAntiMoniker(&pMoniker);
645 if (FAILED(hr))
646 return hr;
648 hr = IMoniker_QueryInterface(pMoniker, riid, ppv);
650 if (FAILED(hr))
651 IMoniker_Release(pMoniker);
653 return hr;