Fixed header dependencies to be fully compatible with the Windows
[wine/multimedia.git] / dlls / ole32 / oleobj.c
blob8a9d2760fd5316081f34fc2412b0d14eca774bf6
1 /*
2 * OLE2 COM objects
4 * Copyright 1998 Eric Kohl
5 * Copyright 1999 Francis Beaudet
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <stdarg.h>
24 #include <string.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winerror.h"
28 #include "wine/debug.h"
29 #include "ole2.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(ole);
33 #define INITIAL_SINKS 10
35 /**************************************************************************
36 * OleAdviseHolderImpl Implementation
38 typedef struct OleAdviseHolderImpl
40 ICOM_VFIELD(IOleAdviseHolder);
42 DWORD ref;
44 DWORD maxSinks;
45 IAdviseSink** arrayOfSinks;
47 } OleAdviseHolderImpl;
49 static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor();
50 static void OleAdviseHolderImpl_Destructor(OleAdviseHolderImpl* ptrToDestroy);
51 static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(LPOLEADVISEHOLDER,REFIID,LPVOID*);
52 static ULONG WINAPI OleAdviseHolderImpl_AddRef(LPOLEADVISEHOLDER);
53 static ULONG WINAPI OleAdviseHolderImpl_Release(LPOLEADVISEHOLDER);
54 static HRESULT WINAPI OleAdviseHolderImpl_Advise(LPOLEADVISEHOLDER, IAdviseSink*, DWORD*);
55 static HRESULT WINAPI OleAdviseHolderImpl_Unadvise (LPOLEADVISEHOLDER, DWORD);
56 static HRESULT WINAPI OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER, IEnumSTATDATA **);
57 static HRESULT WINAPI OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER, IMoniker *);
58 static HRESULT WINAPI OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER);
59 static HRESULT WINAPI OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER);
62 /**************************************************************************
63 * OleAdviseHolderImpl_VTable
65 static struct ICOM_VTABLE(IOleAdviseHolder) oahvt =
67 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
68 OleAdviseHolderImpl_QueryInterface,
69 OleAdviseHolderImpl_AddRef,
70 OleAdviseHolderImpl_Release,
71 OleAdviseHolderImpl_Advise,
72 OleAdviseHolderImpl_Unadvise,
73 OleAdviseHolderImpl_EnumAdvise,
74 OleAdviseHolderImpl_SendOnRename,
75 OleAdviseHolderImpl_SendOnSave,
76 OleAdviseHolderImpl_SendOnClose
79 /**************************************************************************
80 * OleAdviseHolderImpl_Constructor
83 static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor()
85 OleAdviseHolderImpl* lpoah;
86 DWORD index;
88 lpoah= (OleAdviseHolderImpl*)HeapAlloc(GetProcessHeap(),
90 sizeof(OleAdviseHolderImpl));
92 lpoah->lpVtbl = &oahvt;
93 lpoah->ref = 1;
94 lpoah->maxSinks = INITIAL_SINKS;
95 lpoah->arrayOfSinks = HeapAlloc(GetProcessHeap(),
97 lpoah->maxSinks * sizeof(IAdviseSink*));
99 for (index = 0; index < lpoah->maxSinks; index++)
100 lpoah->arrayOfSinks[index]=0;
102 TRACE("returning %p\n", lpoah);
103 return (LPOLEADVISEHOLDER)lpoah;
106 /**************************************************************************
107 * OleAdviseHolderImpl_Destructor
109 static void OleAdviseHolderImpl_Destructor(
110 OleAdviseHolderImpl* ptrToDestroy)
112 DWORD index;
113 TRACE("%p\n", ptrToDestroy);
115 for (index = 0; index < ptrToDestroy->maxSinks; index++)
117 if (ptrToDestroy->arrayOfSinks[index]!=0)
119 IAdviseSink_Release(ptrToDestroy->arrayOfSinks[index]);
120 ptrToDestroy->arrayOfSinks[index] = NULL;
124 HeapFree(GetProcessHeap(),
126 ptrToDestroy->arrayOfSinks);
129 HeapFree(GetProcessHeap(),
131 ptrToDestroy);
134 /**************************************************************************
135 * OleAdviseHolderImpl_QueryInterface
137 static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(
138 LPOLEADVISEHOLDER iface,
139 REFIID riid,
140 LPVOID* ppvObj)
142 ICOM_THIS(OleAdviseHolderImpl, iface);
143 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObj);
145 * Sanity check
147 if (ppvObj==NULL)
148 return E_POINTER;
150 *ppvObj = NULL;
152 if (IsEqualIID(riid, &IID_IUnknown))
154 /* IUnknown */
155 *ppvObj = This;
157 else if(IsEqualIID(riid, &IID_IOleAdviseHolder))
159 /* IOleAdviseHolder */
160 *ppvObj = (IOleAdviseHolder*) This;
163 if(*ppvObj == NULL)
164 return E_NOINTERFACE;
167 * A successful QI always increments the reference count.
169 IUnknown_AddRef((IUnknown*)*ppvObj);
171 return S_OK;
174 /******************************************************************************
175 * OleAdviseHolderImpl_AddRef
177 static ULONG WINAPI OleAdviseHolderImpl_AddRef(
178 LPOLEADVISEHOLDER iface)
180 ICOM_THIS(OleAdviseHolderImpl, iface);
181 TRACE("(%p)->(ref=%ld)\n", This, This->ref);
182 return ++(This->ref);
185 /******************************************************************************
186 * OleAdviseHolderImpl_Release
188 static ULONG WINAPI OleAdviseHolderImpl_Release(
189 LPOLEADVISEHOLDER iface)
191 ICOM_THIS(OleAdviseHolderImpl, iface);
192 TRACE("(%p)->(ref=%ld)\n", This, This->ref);
193 This->ref--;
195 if (This->ref == 0)
197 OleAdviseHolderImpl_Destructor(This);
199 return 0;
202 return This->ref;
205 /******************************************************************************
206 * OleAdviseHolderImpl_Advise
208 static HRESULT WINAPI OleAdviseHolderImpl_Advise(
209 LPOLEADVISEHOLDER iface,
210 IAdviseSink* pAdvise,
211 DWORD* pdwConnection)
213 DWORD index;
215 ICOM_THIS(OleAdviseHolderImpl, iface);
217 TRACE("(%p)->(%p, %p)\n", This, pAdvise, pdwConnection);
220 * Sanity check
222 if (pdwConnection==NULL)
223 return E_POINTER;
225 *pdwConnection = 0;
228 * Find a free spot in the array.
230 for (index = 0; index < This->maxSinks; index++)
232 if (This->arrayOfSinks[index]==NULL)
233 break;
237 * If the array is full, we need to grow it.
239 if (index == This->maxSinks)
241 DWORD i;
243 This->maxSinks+=INITIAL_SINKS;
245 This->arrayOfSinks = HeapReAlloc(GetProcessHeap(),
247 This->arrayOfSinks,
248 This->maxSinks*sizeof(IAdviseSink*));
250 for (i=index;i < This->maxSinks; i++)
251 This->arrayOfSinks[i]=0;
255 * Store the new sink
257 This->arrayOfSinks[index] = pAdvise;
259 if (This->arrayOfSinks[index]!=NULL)
260 IAdviseSink_AddRef(This->arrayOfSinks[index]);
263 * Return the index as the cookie.
264 * Since 0 is not a valid cookie, we will increment by
265 * 1 the index in the table.
267 *pdwConnection = index+1;
269 return S_OK;
272 /******************************************************************************
273 * OleAdviseHolderImpl_Unadvise
275 static HRESULT WINAPI OleAdviseHolderImpl_Unadvise(
276 LPOLEADVISEHOLDER iface,
277 DWORD dwConnection)
279 ICOM_THIS(OleAdviseHolderImpl, iface);
281 TRACE("(%p)->(%lu)\n", This, dwConnection);
284 * So we don't return 0 as a cookie, the index was
285 * incremented by 1 in OleAdviseHolderImpl_Advise
286 * we have to compensate.
288 dwConnection--;
291 * Check for invalid cookies.
293 if (dwConnection >= This->maxSinks)
294 return OLE_E_NOCONNECTION;
296 if (This->arrayOfSinks[dwConnection] == NULL)
297 return OLE_E_NOCONNECTION;
300 * Release the sink and mark the spot in the list as free.
302 IAdviseSink_Release(This->arrayOfSinks[dwConnection]);
303 This->arrayOfSinks[dwConnection] = NULL;
305 return S_OK;
308 /******************************************************************************
309 * OleAdviseHolderImpl_EnumAdvise
311 static HRESULT WINAPI
312 OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER iface, IEnumSTATDATA **ppenumAdvise)
314 ICOM_THIS(OleAdviseHolderImpl, iface);
315 FIXME("(%p)->(%p)\n", This, ppenumAdvise);
317 *ppenumAdvise = NULL;
319 return S_OK;
322 /******************************************************************************
323 * OleAdviseHolderImpl_SendOnRename
325 static HRESULT WINAPI
326 OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk)
328 ICOM_THIS(OleAdviseHolderImpl, iface);
329 FIXME("(%p)->(%p)\n", This, pmk);
332 return S_OK;
335 /******************************************************************************
336 * OleAdviseHolderImpl_SendOnSave
338 static HRESULT WINAPI
339 OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface)
341 ICOM_THIS(OleAdviseHolderImpl, iface);
342 FIXME("(%p)\n", This);
344 return S_OK;
347 /******************************************************************************
348 * OleAdviseHolderImpl_SendOnClose
350 static HRESULT WINAPI
351 OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface)
353 ICOM_THIS(OleAdviseHolderImpl, iface);
354 FIXME("(%p)\n", This);
357 return S_OK;
360 /**************************************************************************
361 * DataAdviseHolder Implementation
363 typedef struct DataAdviseConnection {
364 IAdviseSink *sink;
365 FORMATETC fmat;
366 DWORD advf;
367 } DataAdviseConnection;
369 typedef struct DataAdviseHolder
371 ICOM_VFIELD(IDataAdviseHolder);
373 DWORD ref;
374 DWORD maxCons;
375 DataAdviseConnection* Connections;
376 } DataAdviseHolder;
378 /**************************************************************************
379 * DataAdviseHolder method prototypes
381 static IDataAdviseHolder* DataAdviseHolder_Constructor();
382 static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy);
383 static HRESULT WINAPI DataAdviseHolder_QueryInterface(
384 IDataAdviseHolder* iface,
385 REFIID riid,
386 void** ppvObject);
387 static ULONG WINAPI DataAdviseHolder_AddRef(
388 IDataAdviseHolder* iface);
389 static ULONG WINAPI DataAdviseHolder_Release(
390 IDataAdviseHolder* iface);
391 static HRESULT WINAPI DataAdviseHolder_Advise(
392 IDataAdviseHolder* iface,
393 IDataObject* pDataObject,
394 FORMATETC* pFetc,
395 DWORD advf,
396 IAdviseSink* pAdvise,
397 DWORD* pdwConnection);
398 static HRESULT WINAPI DataAdviseHolder_Unadvise(
399 IDataAdviseHolder* iface,
400 DWORD dwConnection);
401 static HRESULT WINAPI DataAdviseHolder_EnumAdvise(
402 IDataAdviseHolder* iface,
403 IEnumSTATDATA** ppenumAdvise);
404 static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
405 IDataAdviseHolder* iface,
406 IDataObject* pDataObject,
407 DWORD dwReserved,
408 DWORD advf);
410 /**************************************************************************
411 * DataAdviseHolderImpl_VTable
413 static struct ICOM_VTABLE(IDataAdviseHolder) DataAdviseHolderImpl_VTable =
415 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
416 DataAdviseHolder_QueryInterface,
417 DataAdviseHolder_AddRef,
418 DataAdviseHolder_Release,
419 DataAdviseHolder_Advise,
420 DataAdviseHolder_Unadvise,
421 DataAdviseHolder_EnumAdvise,
422 DataAdviseHolder_SendOnDataChange
425 /******************************************************************************
426 * DataAdviseHolder_Constructor
428 static IDataAdviseHolder* DataAdviseHolder_Constructor()
430 DataAdviseHolder* newHolder;
432 newHolder = (DataAdviseHolder*)HeapAlloc(GetProcessHeap(),
434 sizeof(DataAdviseHolder));
436 newHolder->lpVtbl = &DataAdviseHolderImpl_VTable;
437 newHolder->ref = 1;
438 newHolder->maxCons = INITIAL_SINKS;
439 newHolder->Connections = HeapAlloc(GetProcessHeap(),
440 HEAP_ZERO_MEMORY,
441 newHolder->maxCons *
442 sizeof(DataAdviseConnection));
444 TRACE("returning %p\n", newHolder);
445 return (IDataAdviseHolder*)newHolder;
448 /******************************************************************************
449 * DataAdviseHolder_Destructor
451 static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy)
453 DWORD index;
454 TRACE("%p\n", ptrToDestroy);
456 for (index = 0; index < ptrToDestroy->maxCons; index++)
458 if (ptrToDestroy->Connections[index].sink != NULL)
460 IAdviseSink_Release(ptrToDestroy->Connections[index].sink);
461 ptrToDestroy->Connections[index].sink = NULL;
465 HeapFree(GetProcessHeap(), 0, ptrToDestroy->Connections);
466 HeapFree(GetProcessHeap(), 0, ptrToDestroy);
469 /************************************************************************
470 * DataAdviseHolder_QueryInterface (IUnknown)
472 * See Windows documentation for more details on IUnknown methods.
474 static HRESULT WINAPI DataAdviseHolder_QueryInterface(
475 IDataAdviseHolder* iface,
476 REFIID riid,
477 void** ppvObject)
479 ICOM_THIS(DataAdviseHolder, iface);
480 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObject);
482 * Perform a sanity check on the parameters.
484 if ( (This==0) || (ppvObject==0) )
485 return E_INVALIDARG;
488 * Initialize the return parameter.
490 *ppvObject = 0;
493 * Compare the riid with the interface IDs implemented by this object.
495 if ( (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) ||
496 (memcmp(&IID_IDataAdviseHolder, riid, sizeof(IID_IDataAdviseHolder)) == 0) )
498 *ppvObject = iface;
502 * Check that we obtained an interface.
504 if ((*ppvObject)==0)
506 return E_NOINTERFACE;
510 * Query Interface always increases the reference count by one when it is
511 * successful.
513 IUnknown_AddRef((IUnknown*)*ppvObject);
515 return S_OK;
518 /************************************************************************
519 * DataAdviseHolder_AddRef (IUnknown)
521 * See Windows documentation for more details on IUnknown methods.
523 static ULONG WINAPI DataAdviseHolder_AddRef(
524 IDataAdviseHolder* iface)
526 ICOM_THIS(DataAdviseHolder, iface);
527 TRACE("(%p) (ref=%ld)\n", This, This->ref);
528 This->ref++;
530 return This->ref;
533 /************************************************************************
534 * DataAdviseHolder_Release (IUnknown)
536 * See Windows documentation for more details on IUnknown methods.
538 static ULONG WINAPI DataAdviseHolder_Release(
539 IDataAdviseHolder* iface)
541 ICOM_THIS(DataAdviseHolder, iface);
542 TRACE("(%p) (ref=%ld)\n", This, This->ref);
545 * Decrease the reference count on this object.
547 This->ref--;
550 * If the reference count goes down to 0, perform suicide.
552 if (This->ref==0)
554 DataAdviseHolder_Destructor(This);
556 return 0;
559 return This->ref;
562 /************************************************************************
563 * DataAdviseHolder_Advise
566 static HRESULT WINAPI DataAdviseHolder_Advise(
567 IDataAdviseHolder* iface,
568 IDataObject* pDataObject,
569 FORMATETC* pFetc,
570 DWORD advf,
571 IAdviseSink* pAdvise,
572 DWORD* pdwConnection)
574 DWORD index;
576 ICOM_THIS(DataAdviseHolder, iface);
578 TRACE("(%p)->(%p, %p, %08lx, %p, %p)\n", This, pDataObject, pFetc, advf,
579 pAdvise, pdwConnection);
581 * Sanity check
583 if (pdwConnection==NULL)
584 return E_POINTER;
586 *pdwConnection = 0;
589 * Find a free spot in the array.
591 for (index = 0; index < This->maxCons; index++)
593 if (This->Connections[index].sink == NULL)
594 break;
598 * If the array is full, we need to grow it.
600 if (index == This->maxCons)
602 This->maxCons+=INITIAL_SINKS;
603 This->Connections = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
604 This->Connections,
605 This->maxCons*sizeof(DataAdviseConnection));
608 * Store the new sink
610 This->Connections[index].sink = pAdvise;
611 memcpy(&(This->Connections[index].fmat), pFetc, sizeof(FORMATETC));
612 This->Connections[index].advf = advf;
614 if (This->Connections[index].sink != NULL) {
615 IAdviseSink_AddRef(This->Connections[index].sink);
616 if(advf & ADVF_PRIMEFIRST) {
617 DataAdviseHolder_SendOnDataChange(iface, pDataObject, 0, advf);
621 * Return the index as the cookie.
622 * Since 0 is not a valid cookie, we will increment by
623 * 1 the index in the table.
625 *pdwConnection = index+1;
627 return S_OK;
630 /******************************************************************************
631 * DataAdviseHolder_Unadvise
633 static HRESULT WINAPI DataAdviseHolder_Unadvise(
634 IDataAdviseHolder* iface,
635 DWORD dwConnection)
637 ICOM_THIS(DataAdviseHolder, iface);
639 TRACE("(%p)->(%lu)\n", This, dwConnection);
642 * So we don't return 0 as a cookie, the index was
643 * incremented by 1 in OleAdviseHolderImpl_Advise
644 * we have to compensate.
646 dwConnection--;
649 * Check for invalid cookies.
651 if (dwConnection >= This->maxCons)
652 return OLE_E_NOCONNECTION;
654 if (This->Connections[dwConnection].sink == NULL)
655 return OLE_E_NOCONNECTION;
658 * Release the sink and mark the spot in the list as free.
660 IAdviseSink_Release(This->Connections[dwConnection].sink);
661 memset(&(This->Connections[dwConnection]), 0, sizeof(DataAdviseConnection));
662 return S_OK;
665 static HRESULT WINAPI DataAdviseHolder_EnumAdvise(
666 IDataAdviseHolder* iface,
667 IEnumSTATDATA** ppenumAdvise)
669 ICOM_THIS(DataAdviseHolder, iface);
671 FIXME("(%p)->(%p)\n", This, ppenumAdvise);
672 return E_NOTIMPL;
675 /******************************************************************************
676 * DataAdviseHolder_SendOnDataChange
678 static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
679 IDataAdviseHolder* iface,
680 IDataObject* pDataObject,
681 DWORD dwReserved,
682 DWORD advf)
684 ICOM_THIS(DataAdviseHolder, iface);
685 DWORD index;
686 STGMEDIUM stg;
687 HRESULT res;
689 TRACE("(%p)->(%p,%08lx,%08lx)\n", This, pDataObject, dwReserved, advf);
691 for(index = 0; index < This->maxCons; index++) {
692 if(This->Connections[index].sink != NULL) {
693 if(!(This->Connections[index].advf & ADVF_NODATA)) {
694 TRACE("Calling IDataObject_GetData\n");
695 res = IDataObject_GetData(pDataObject,
696 &(This->Connections[index].fmat),
697 &stg);
698 TRACE("returns %08lx\n", res);
700 TRACE("Calling IAdviseSink_OnDataChange\n");
701 IAdviseSink_OnDataChange(This->Connections[index].sink,
702 &(This->Connections[index].fmat),
703 &stg);
704 TRACE("Done IAdviseSink_OnDataChange\n");
705 if(This->Connections[index].advf & ADVF_ONLYONCE) {
706 TRACE("Removing connection\n");
707 DataAdviseHolder_Unadvise(iface, index+1);
711 return S_OK;
714 /***********************************************************************
715 * API functions
718 /***********************************************************************
719 * CreateOleAdviseHolder [OLE32.59]
721 HRESULT WINAPI CreateOleAdviseHolder(
722 LPOLEADVISEHOLDER *ppOAHolder)
724 TRACE("(%p)\n", ppOAHolder);
727 * Sanity check,
729 if (ppOAHolder==NULL)
730 return E_POINTER;
732 *ppOAHolder = OleAdviseHolderImpl_Constructor ();
734 if (*ppOAHolder != NULL)
735 return S_OK;
737 return E_OUTOFMEMORY;
740 /******************************************************************************
741 * CreateDataAdviseHolder [OLE32.53]
743 HRESULT WINAPI CreateDataAdviseHolder(
744 LPDATAADVISEHOLDER* ppDAHolder)
746 TRACE("(%p)\n", ppDAHolder);
749 * Sanity check,
751 if (ppDAHolder==NULL)
752 return E_POINTER;
754 *ppDAHolder = DataAdviseHolder_Constructor();
756 if (*ppDAHolder != NULL)
757 return S_OK;
759 return E_OUTOFMEMORY;