dmband: Rewrite band lbin list parsing.
[wine.git] / dlls / ole32 / antimoniker.c
blob401162c300b9fec4bfa4185d5ad84d576e0ab444
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 <stdarg.h>
22 #include <string.h>
24 #define COBJMACROS
25 #include "windef.h"
26 #include "winbase.h"
27 #include "objbase.h"
28 #include "wine/debug.h"
29 #include "moniker.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(ole);
33 /* AntiMoniker data structure */
34 typedef struct AntiMonikerImpl{
35 IMoniker IMoniker_iface;
36 IROTData IROTData_iface;
37 LONG refcount;
38 IUnknown *pMarshal; /* custom marshaler */
39 DWORD count;
40 } AntiMonikerImpl;
42 static inline AntiMonikerImpl *impl_from_IMoniker(IMoniker *iface)
44 return CONTAINING_RECORD(iface, AntiMonikerImpl, IMoniker_iface);
47 static inline AntiMonikerImpl *impl_from_IROTData(IROTData *iface)
49 return CONTAINING_RECORD(iface, AntiMonikerImpl, IROTData_iface);
52 static AntiMonikerImpl *unsafe_impl_from_IMoniker(IMoniker *iface);
54 BOOL is_anti_moniker(IMoniker *iface, DWORD *order)
56 AntiMonikerImpl *moniker = unsafe_impl_from_IMoniker(iface);
58 if (!moniker)
60 *order = 0;
61 return FALSE;
64 *order = moniker->count;
66 return TRUE;
69 /*******************************************************************************
70 * AntiMoniker_QueryInterface
71 *******************************************************************************/
72 static HRESULT WINAPI
73 AntiMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void** ppvObject)
75 AntiMonikerImpl *This = impl_from_IMoniker(iface);
77 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
79 if ( ppvObject==0 )
80 return E_INVALIDARG;
82 *ppvObject = 0;
84 if (IsEqualIID(&IID_IUnknown, riid) ||
85 IsEqualIID(&IID_IPersist, riid) ||
86 IsEqualIID(&IID_IPersistStream, riid) ||
87 IsEqualIID(&IID_IMoniker, riid) ||
88 IsEqualGUID(&CLSID_AntiMoniker, riid))
90 *ppvObject = iface;
92 else if (IsEqualIID(&IID_IROTData, riid))
93 *ppvObject = &This->IROTData_iface;
94 else if (IsEqualIID(&IID_IMarshal, riid))
96 HRESULT hr = S_OK;
97 if (!This->pMarshal)
98 hr = MonikerMarshal_Create(iface, &This->pMarshal);
99 if (hr != S_OK)
100 return hr;
101 return IUnknown_QueryInterface(This->pMarshal, riid, ppvObject);
104 if ((*ppvObject)==0)
105 return E_NOINTERFACE;
107 IMoniker_AddRef(iface);
109 return S_OK;
112 /******************************************************************************
113 * AntiMoniker_AddRef
114 ******************************************************************************/
115 static ULONG WINAPI AntiMonikerImpl_AddRef(IMoniker *iface)
117 AntiMonikerImpl *moniker = impl_from_IMoniker(iface);
118 ULONG refcount = InterlockedIncrement(&moniker->refcount);
120 TRACE("%p, refcount %lu.\n", iface, refcount);
122 return refcount;
125 /******************************************************************************
126 * AntiMoniker_Release
127 ******************************************************************************/
128 static ULONG WINAPI AntiMonikerImpl_Release(IMoniker *iface)
130 AntiMonikerImpl *moniker = impl_from_IMoniker(iface);
131 ULONG refcount = InterlockedDecrement(&moniker->refcount);
133 TRACE("%p, refcount %lu.\n", iface, refcount);
135 if (!refcount)
137 if (moniker->pMarshal) IUnknown_Release(moniker->pMarshal);
138 free(moniker);
141 return refcount;
144 /******************************************************************************
145 * AntiMoniker_GetClassID
146 ******************************************************************************/
147 static HRESULT WINAPI
148 AntiMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
150 TRACE("(%p,%p)\n",iface,pClassID);
152 if (pClassID==NULL)
153 return E_POINTER;
155 *pClassID = CLSID_AntiMoniker;
157 return S_OK;
160 /******************************************************************************
161 * AntiMoniker_IsDirty
162 ******************************************************************************/
163 static HRESULT WINAPI
164 AntiMonikerImpl_IsDirty(IMoniker* iface)
166 /* Note that the OLE-provided implementations of the IPersistStream::IsDirty
167 method in the OLE-provided moniker interfaces always return S_FALSE because
168 their internal state never changes. */
170 TRACE("(%p)\n",iface);
172 return S_FALSE;
175 /******************************************************************************
176 * AntiMoniker_Load
177 ******************************************************************************/
178 static HRESULT WINAPI AntiMonikerImpl_Load(IMoniker *iface, IStream *stream)
180 AntiMonikerImpl *moniker = impl_from_IMoniker(iface);
181 DWORD count = 0;
182 HRESULT hr;
184 TRACE("%p, %p.\n", iface, stream);
186 if (FAILED(hr = IStream_Read(stream, &count, sizeof(count), NULL)))
187 return hr;
189 if (count > 0xfffff)
190 return E_INVALIDARG;
192 moniker->count = count;
194 return S_OK;
197 /******************************************************************************
198 * AntiMoniker_Save
199 ******************************************************************************/
200 static HRESULT WINAPI AntiMonikerImpl_Save(IMoniker *iface, IStream *stream, BOOL clear_dirty)
202 AntiMonikerImpl *moniker = impl_from_IMoniker(iface);
204 TRACE("%p, %p, %d.\n", iface, stream, clear_dirty);
206 return IStream_Write(stream, &moniker->count, sizeof(moniker->count), NULL);
209 /******************************************************************************
210 * AntiMoniker_GetSizeMax
212 * PARAMS
213 * pcbSize [out] Pointer to size of stream needed to save object
214 ******************************************************************************/
215 static HRESULT WINAPI
216 AntiMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
218 TRACE("(%p,%p)\n",iface,pcbSize);
220 if (!pcbSize)
221 return E_POINTER;
223 /* for more details see AntiMonikerImpl_Save comments */
226 * Normally the sizemax must be sizeof DWORD, but
227 * I tested this function it usually return 16 bytes
228 * more than the number of bytes used by AntiMoniker::Save function
230 pcbSize->u.LowPart = sizeof(DWORD)+16;
232 pcbSize->u.HighPart=0;
234 return S_OK;
237 /******************************************************************************
238 * AntiMoniker_BindToObject
239 ******************************************************************************/
240 static HRESULT WINAPI
241 AntiMonikerImpl_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
242 REFIID riid, VOID** ppvResult)
244 TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
245 return E_NOTIMPL;
248 /******************************************************************************
249 * AntiMoniker_BindToStorage
250 ******************************************************************************/
251 static HRESULT WINAPI
252 AntiMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
253 REFIID riid, VOID** ppvResult)
255 TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
256 return E_NOTIMPL;
259 static HRESULT WINAPI
260 AntiMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
261 IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
263 TRACE("%p, %p, %ld, %p, %p.\n", iface, pbc, dwReduceHowFar, ppmkToLeft, ppmkReduced);
265 if (ppmkReduced==NULL)
266 return E_POINTER;
268 AntiMonikerImpl_AddRef(iface);
270 *ppmkReduced=iface;
272 return MK_S_REDUCED_TO_SELF;
274 /******************************************************************************
275 * AntiMoniker_ComposeWith
276 ******************************************************************************/
277 static HRESULT WINAPI
278 AntiMonikerImpl_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
279 BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
282 TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
284 if ((ppmkComposite==NULL)||(pmkRight==NULL))
285 return E_POINTER;
287 *ppmkComposite=0;
289 if (fOnlyIfNotGeneric)
290 return MK_E_NEEDGENERIC;
291 else
292 return CreateGenericComposite(iface,pmkRight,ppmkComposite);
295 static HRESULT WINAPI AntiMonikerImpl_Enum(IMoniker *iface, BOOL forward, IEnumMoniker **ppenumMoniker)
297 TRACE("%p, %d, %p.\n", iface, forward, ppenumMoniker);
299 if (ppenumMoniker == NULL)
300 return E_INVALIDARG;
302 *ppenumMoniker = NULL;
304 return S_OK;
307 /******************************************************************************
308 * AntiMoniker_IsEqual
309 ******************************************************************************/
310 static HRESULT WINAPI AntiMonikerImpl_IsEqual(IMoniker *iface, IMoniker *other)
312 AntiMonikerImpl *moniker = impl_from_IMoniker(iface), *other_moniker;
314 TRACE("%p, %p.\n", iface, other);
316 if (!other)
317 return E_INVALIDARG;
319 other_moniker = unsafe_impl_from_IMoniker(other);
320 if (!other_moniker)
321 return S_FALSE;
323 return moniker->count == other_moniker->count ? S_OK : S_FALSE;
326 /******************************************************************************
327 * AntiMoniker_Hash
328 ******************************************************************************/
329 static HRESULT WINAPI AntiMonikerImpl_Hash(IMoniker *iface, DWORD *hash)
331 AntiMonikerImpl *moniker = impl_from_IMoniker(iface);
333 TRACE("%p, %p.\n", iface, hash);
335 if (!hash)
336 return E_POINTER;
338 *hash = 0x80000000 | moniker->count;
340 return S_OK;
343 /******************************************************************************
344 * AntiMoniker_IsRunning
345 ******************************************************************************/
346 static HRESULT WINAPI
347 AntiMonikerImpl_IsRunning(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
348 IMoniker* pmkNewlyRunning)
350 IRunningObjectTable* rot;
351 HRESULT res;
353 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
355 if (pbc==NULL)
356 return E_INVALIDARG;
358 res=IBindCtx_GetRunningObjectTable(pbc,&rot);
360 if (FAILED(res))
361 return res;
363 res = IRunningObjectTable_IsRunning(rot,iface);
365 IRunningObjectTable_Release(rot);
367 return res;
370 /******************************************************************************
371 * AntiMoniker_GetTimeOfLastChange
372 ******************************************************************************/
373 static HRESULT WINAPI AntiMonikerImpl_GetTimeOfLastChange(IMoniker* iface,
374 IBindCtx* pbc,
375 IMoniker* pmkToLeft,
376 FILETIME* pAntiTime)
378 TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pAntiTime);
379 return E_NOTIMPL;
382 /******************************************************************************
383 * AntiMoniker_Inverse
384 ******************************************************************************/
385 static HRESULT WINAPI
386 AntiMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
388 TRACE("(%p,%p)\n",iface,ppmk);
390 if (ppmk==NULL)
391 return E_POINTER;
393 *ppmk=0;
395 return MK_E_NOINVERSE;
398 /******************************************************************************
399 * AntiMoniker_CommonPrefixWith
400 ******************************************************************************/
401 static HRESULT WINAPI AntiMonikerImpl_CommonPrefixWith(IMoniker *iface, IMoniker *other, IMoniker **prefix)
403 AntiMonikerImpl *moniker = impl_from_IMoniker(iface), *other_moniker;
404 HRESULT hr;
406 TRACE("%p, %p, %p.\n", iface, other, prefix);
408 other_moniker = unsafe_impl_from_IMoniker(other);
409 if (other_moniker)
411 if (moniker->count <= other_moniker->count)
413 *prefix = iface;
414 hr = moniker->count == other_moniker->count ? MK_S_US : MK_S_ME;
416 else
418 *prefix = other;
419 hr = MK_S_HIM;
422 IMoniker_AddRef(*prefix);
423 return hr;
426 return MonikerCommonPrefixWith(iface, other, prefix);
429 static HRESULT WINAPI AntiMonikerImpl_RelativePathTo(IMoniker *iface, IMoniker *other, IMoniker **result)
431 TRACE("%p, %p, %p.\n", iface, other, result);
433 if (!other || !result)
434 return E_INVALIDARG;
436 IMoniker_AddRef(other);
437 *result = other;
439 return MK_S_HIM;
442 /******************************************************************************
443 * AntiMoniker_GetDisplayName
444 ******************************************************************************/
445 static HRESULT WINAPI
446 AntiMonikerImpl_GetDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR *displayname)
448 AntiMonikerImpl *moniker = impl_from_IMoniker(iface);
449 static const WCHAR nameW[] = {'\\','.','.'};
450 WCHAR *ptrW;
451 int i;
453 TRACE("%p, %p, %p, %p.\n", iface, pbc, pmkToLeft, displayname);
455 if (!displayname)
456 return E_POINTER;
458 if (pmkToLeft!=NULL){
459 FIXME("() pmkToLeft!=NULL not implemented\n");
460 return E_NOTIMPL;
463 *displayname = ptrW = CoTaskMemAlloc((moniker->count * ARRAY_SIZE(nameW) + 1) * sizeof(WCHAR));
464 if (!*displayname)
465 return E_OUTOFMEMORY;
467 for (i = 0; i < moniker->count; ++i)
468 memcpy(ptrW + i * ARRAY_SIZE(nameW), nameW, sizeof(nameW));
469 ptrW[moniker->count * ARRAY_SIZE(nameW)] = 0;
471 return S_OK;
474 /******************************************************************************
475 * AntiMoniker_ParseDisplayName
476 ******************************************************************************/
477 static HRESULT WINAPI
478 AntiMonikerImpl_ParseDisplayName(IMoniker* iface, IBindCtx* pbc,
479 IMoniker* pmkToLeft, LPOLESTR pszDisplayName,
480 ULONG* pchEaten, IMoniker** ppmkOut)
482 TRACE("(%p,%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);
483 return E_NOTIMPL;
486 /******************************************************************************
487 * AntiMoniker_IsSystemMoniker
488 ******************************************************************************/
489 static HRESULT WINAPI
490 AntiMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
492 TRACE("(%p,%p)\n",iface,pwdMksys);
494 if (!pwdMksys)
495 return E_POINTER;
497 (*pwdMksys)=MKSYS_ANTIMONIKER;
499 return S_OK;
502 /*******************************************************************************
503 * AntiMonikerIROTData_QueryInterface
504 *******************************************************************************/
505 static HRESULT WINAPI
506 AntiMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
508 AntiMonikerImpl *This = impl_from_IROTData(iface);
510 TRACE("(%p,%s,%p)\n",iface,debugstr_guid(riid),ppvObject);
512 return AntiMonikerImpl_QueryInterface(&This->IMoniker_iface, riid, ppvObject);
515 /***********************************************************************
516 * AntiMonikerIROTData_AddRef
518 static ULONG WINAPI AntiMonikerROTDataImpl_AddRef(IROTData *iface)
520 AntiMonikerImpl *This = impl_from_IROTData(iface);
522 TRACE("(%p)\n",iface);
524 return AntiMonikerImpl_AddRef(&This->IMoniker_iface);
527 /***********************************************************************
528 * AntiMonikerIROTData_Release
530 static ULONG WINAPI AntiMonikerROTDataImpl_Release(IROTData* iface)
532 AntiMonikerImpl *This = impl_from_IROTData(iface);
534 TRACE("(%p)\n",iface);
536 return AntiMonikerImpl_Release(&This->IMoniker_iface);
539 /******************************************************************************
540 * AntiMonikerIROTData_GetComparisonData
541 ******************************************************************************/
542 static HRESULT WINAPI
543 AntiMonikerROTDataImpl_GetComparisonData(IROTData *iface, BYTE *data, ULONG data_len, ULONG *data_req)
545 AntiMonikerImpl *moniker = impl_from_IROTData(iface);
547 TRACE("%p, %p, %lu, %p.\n", iface, data, data_len, data_req);
549 *data_req = sizeof(CLSID) + sizeof(DWORD);
550 if (data_len < *data_req)
551 return E_OUTOFMEMORY;
553 memcpy(data, &CLSID_AntiMoniker, sizeof(CLSID));
554 memcpy(data + sizeof(CLSID), &moniker->count, sizeof(moniker->count));
556 return S_OK;
559 /********************************************************************************/
560 /* Virtual function table for the AntiMonikerImpl class which include IPersist,*/
561 /* IPersistStream and IMoniker functions. */
562 static const IMonikerVtbl VT_AntiMonikerImpl =
564 AntiMonikerImpl_QueryInterface,
565 AntiMonikerImpl_AddRef,
566 AntiMonikerImpl_Release,
567 AntiMonikerImpl_GetClassID,
568 AntiMonikerImpl_IsDirty,
569 AntiMonikerImpl_Load,
570 AntiMonikerImpl_Save,
571 AntiMonikerImpl_GetSizeMax,
572 AntiMonikerImpl_BindToObject,
573 AntiMonikerImpl_BindToStorage,
574 AntiMonikerImpl_Reduce,
575 AntiMonikerImpl_ComposeWith,
576 AntiMonikerImpl_Enum,
577 AntiMonikerImpl_IsEqual,
578 AntiMonikerImpl_Hash,
579 AntiMonikerImpl_IsRunning,
580 AntiMonikerImpl_GetTimeOfLastChange,
581 AntiMonikerImpl_Inverse,
582 AntiMonikerImpl_CommonPrefixWith,
583 AntiMonikerImpl_RelativePathTo,
584 AntiMonikerImpl_GetDisplayName,
585 AntiMonikerImpl_ParseDisplayName,
586 AntiMonikerImpl_IsSystemMoniker
589 static AntiMonikerImpl *unsafe_impl_from_IMoniker(IMoniker *iface)
591 if (iface->lpVtbl != &VT_AntiMonikerImpl)
592 return NULL;
593 return CONTAINING_RECORD(iface, AntiMonikerImpl, IMoniker_iface);
596 /********************************************************************************/
597 /* Virtual function table for the IROTData class. */
598 static const IROTDataVtbl VT_ROTDataImpl =
600 AntiMonikerROTDataImpl_QueryInterface,
601 AntiMonikerROTDataImpl_AddRef,
602 AntiMonikerROTDataImpl_Release,
603 AntiMonikerROTDataImpl_GetComparisonData
606 HRESULT create_anti_moniker(DWORD order, IMoniker **ret)
608 AntiMonikerImpl *moniker;
610 if (!(moniker = calloc(1, sizeof(*moniker))))
611 return E_OUTOFMEMORY;
613 moniker->IMoniker_iface.lpVtbl = &VT_AntiMonikerImpl;
614 moniker->IROTData_iface.lpVtbl = &VT_ROTDataImpl;
615 moniker->refcount = 1;
616 moniker->count = order;
618 *ret = &moniker->IMoniker_iface;
620 return S_OK;
623 /******************************************************************************
624 * CreateAntiMoniker [OLE32.@]
625 ******************************************************************************/
626 HRESULT WINAPI CreateAntiMoniker(IMoniker **moniker)
628 TRACE("%p.\n", moniker);
630 return create_anti_moniker(1, moniker);
633 HRESULT WINAPI AntiMoniker_CreateInstance(IClassFactory *iface,
634 IUnknown *pUnk, REFIID riid, void **ppv)
636 IMoniker *pMoniker;
637 HRESULT hr;
639 TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
641 *ppv = NULL;
643 if (pUnk)
644 return CLASS_E_NOAGGREGATION;
646 hr = CreateAntiMoniker(&pMoniker);
647 if (FAILED(hr))
648 return hr;
650 hr = IMoniker_QueryInterface(pMoniker, riid, ppv);
651 IMoniker_Release(pMoniker);
653 return hr;