Removed obsolete INT_Int31Handler.
[wine/multimedia.git] / dlls / ole32 / oleobj.c
blob67b867f331497f6283c5561484334a99ffd38e35
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 <string.h>
24 #include "winbase.h"
25 #include "winerror.h"
26 #include "wine/debug.h"
27 #include "oleidl.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(ole);
31 #define INITIAL_SINKS 10
33 /**************************************************************************
34 * OleAdviseHolderImpl Implementation
36 typedef struct OleAdviseHolderImpl
38 ICOM_VFIELD(IOleAdviseHolder);
40 DWORD ref;
42 DWORD maxSinks;
43 IAdviseSink** arrayOfSinks;
45 } OleAdviseHolderImpl;
47 static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor();
48 static void OleAdviseHolderImpl_Destructor(OleAdviseHolderImpl* ptrToDestroy);
49 static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(LPOLEADVISEHOLDER,REFIID,LPVOID*);
50 static ULONG WINAPI OleAdviseHolderImpl_AddRef(LPOLEADVISEHOLDER);
51 static ULONG WINAPI OleAdviseHolderImpl_Release(LPOLEADVISEHOLDER);
52 static HRESULT WINAPI OleAdviseHolderImpl_Advise(LPOLEADVISEHOLDER, IAdviseSink*, DWORD*);
53 static HRESULT WINAPI OleAdviseHolderImpl_Unadvise (LPOLEADVISEHOLDER, DWORD);
54 static HRESULT WINAPI OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER, IEnumSTATDATA **);
55 static HRESULT WINAPI OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER, IMoniker *);
56 static HRESULT WINAPI OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER);
57 static HRESULT WINAPI OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER);
60 /**************************************************************************
61 * OleAdviseHolderImpl_VTable
63 static struct ICOM_VTABLE(IOleAdviseHolder) oahvt =
65 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
66 OleAdviseHolderImpl_QueryInterface,
67 OleAdviseHolderImpl_AddRef,
68 OleAdviseHolderImpl_Release,
69 OleAdviseHolderImpl_Advise,
70 OleAdviseHolderImpl_Unadvise,
71 OleAdviseHolderImpl_EnumAdvise,
72 OleAdviseHolderImpl_SendOnRename,
73 OleAdviseHolderImpl_SendOnSave,
74 OleAdviseHolderImpl_SendOnClose
77 /**************************************************************************
78 * OleAdviseHolderImpl_Constructor
81 static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor()
83 OleAdviseHolderImpl* lpoah;
84 DWORD index;
86 lpoah= (OleAdviseHolderImpl*)HeapAlloc(GetProcessHeap(),
88 sizeof(OleAdviseHolderImpl));
90 ICOM_VTBL(lpoah) = &oahvt;
91 lpoah->ref = 1;
92 lpoah->maxSinks = INITIAL_SINKS;
93 lpoah->arrayOfSinks = HeapAlloc(GetProcessHeap(),
95 lpoah->maxSinks * sizeof(IAdviseSink*));
97 for (index = 0; index < lpoah->maxSinks; index++)
98 lpoah->arrayOfSinks[index]=0;
100 TRACE("returning %p\n", lpoah);
101 return (LPOLEADVISEHOLDER)lpoah;
104 /**************************************************************************
105 * OleAdviseHolderImpl_Destructor
107 static void OleAdviseHolderImpl_Destructor(
108 OleAdviseHolderImpl* ptrToDestroy)
110 DWORD index;
111 TRACE("%p\n", ptrToDestroy);
113 for (index = 0; index < ptrToDestroy->maxSinks; index++)
115 if (ptrToDestroy->arrayOfSinks[index]!=0)
117 IAdviseSink_Release(ptrToDestroy->arrayOfSinks[index]);
118 ptrToDestroy->arrayOfSinks[index] = NULL;
122 HeapFree(GetProcessHeap(),
124 ptrToDestroy->arrayOfSinks);
127 HeapFree(GetProcessHeap(),
129 ptrToDestroy);
132 /**************************************************************************
133 * OleAdviseHolderImpl_QueryInterface
135 static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(
136 LPOLEADVISEHOLDER iface,
137 REFIID riid,
138 LPVOID* ppvObj)
140 ICOM_THIS(OleAdviseHolderImpl, iface);
141 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObj);
143 * Sanity check
145 if (ppvObj==NULL)
146 return E_POINTER;
148 *ppvObj = NULL;
150 if (IsEqualIID(riid, &IID_IUnknown))
152 /* IUnknown */
153 *ppvObj = This;
155 else if(IsEqualIID(riid, &IID_IOleAdviseHolder))
157 /* IOleAdviseHolder */
158 *ppvObj = (IOleAdviseHolder*) This;
161 if(*ppvObj == NULL)
162 return E_NOINTERFACE;
165 * A successful QI always increments the reference count.
167 IUnknown_AddRef((IUnknown*)*ppvObj);
169 return S_OK;
172 /******************************************************************************
173 * OleAdviseHolderImpl_AddRef
175 static ULONG WINAPI OleAdviseHolderImpl_AddRef(
176 LPOLEADVISEHOLDER iface)
178 ICOM_THIS(OleAdviseHolderImpl, iface);
179 TRACE("(%p)->(ref=%ld)\n", This, This->ref);
180 return ++(This->ref);
183 /******************************************************************************
184 * OleAdviseHolderImpl_Release
186 static ULONG WINAPI OleAdviseHolderImpl_Release(
187 LPOLEADVISEHOLDER iface)
189 ICOM_THIS(OleAdviseHolderImpl, iface);
190 TRACE("(%p)->(ref=%ld)\n", This, This->ref);
191 This->ref--;
193 if (This->ref == 0)
195 OleAdviseHolderImpl_Destructor(This);
197 return 0;
200 return This->ref;
203 /******************************************************************************
204 * OleAdviseHolderImpl_Advise
206 static HRESULT WINAPI OleAdviseHolderImpl_Advise(
207 LPOLEADVISEHOLDER iface,
208 IAdviseSink* pAdvise,
209 DWORD* pdwConnection)
211 DWORD index;
213 ICOM_THIS(OleAdviseHolderImpl, iface);
215 TRACE("(%p)->(%p, %p)\n", This, pAdvise, pdwConnection);
218 * Sanity check
220 if (pdwConnection==NULL)
221 return E_POINTER;
223 *pdwConnection = 0;
226 * Find a free spot in the array.
228 for (index = 0; index < This->maxSinks; index++)
230 if (This->arrayOfSinks[index]==NULL)
231 break;
235 * If the array is full, we need to grow it.
237 if (index == This->maxSinks)
239 DWORD i;
241 This->maxSinks+=INITIAL_SINKS;
243 This->arrayOfSinks = HeapReAlloc(GetProcessHeap(),
245 This->arrayOfSinks,
246 This->maxSinks*sizeof(IAdviseSink*));
248 for (i=index;i < This->maxSinks; i++)
249 This->arrayOfSinks[i]=0;
253 * Store the new sink
255 This->arrayOfSinks[index] = pAdvise;
257 if (This->arrayOfSinks[index]!=NULL)
258 IAdviseSink_AddRef(This->arrayOfSinks[index]);
261 * Return the index as the cookie.
262 * Since 0 is not a valid cookie, we will increment by
263 * 1 the index in the table.
265 *pdwConnection = index+1;
267 return S_OK;
270 /******************************************************************************
271 * OleAdviseHolderImpl_Unadvise
273 static HRESULT WINAPI OleAdviseHolderImpl_Unadvise(
274 LPOLEADVISEHOLDER iface,
275 DWORD dwConnection)
277 ICOM_THIS(OleAdviseHolderImpl, iface);
279 TRACE("(%p)->(%lu)\n", This, dwConnection);
282 * So we don't return 0 as a cookie, the index was
283 * incremented by 1 in OleAdviseHolderImpl_Advise
284 * we have to compensate.
286 dwConnection--;
289 * Check for invalid cookies.
291 if (dwConnection >= This->maxSinks)
292 return OLE_E_NOCONNECTION;
294 if (This->arrayOfSinks[dwConnection] == NULL)
295 return OLE_E_NOCONNECTION;
298 * Release the sink and mark the spot in the list as free.
300 IAdviseSink_Release(This->arrayOfSinks[dwConnection]);
301 This->arrayOfSinks[dwConnection] = NULL;
303 return S_OK;
306 /******************************************************************************
307 * OleAdviseHolderImpl_EnumAdvise
309 static HRESULT WINAPI
310 OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER iface, IEnumSTATDATA **ppenumAdvise)
312 ICOM_THIS(OleAdviseHolderImpl, iface);
313 FIXME("(%p)->(%p)\n", This, ppenumAdvise);
315 *ppenumAdvise = NULL;
317 return S_OK;
320 /******************************************************************************
321 * OleAdviseHolderImpl_SendOnRename
323 static HRESULT WINAPI
324 OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk)
326 ICOM_THIS(OleAdviseHolderImpl, iface);
327 FIXME("(%p)->(%p)\n", This, pmk);
330 return S_OK;
333 /******************************************************************************
334 * OleAdviseHolderImpl_SendOnSave
336 static HRESULT WINAPI
337 OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface)
339 ICOM_THIS(OleAdviseHolderImpl, iface);
340 FIXME("(%p)\n", This);
342 return S_OK;
345 /******************************************************************************
346 * OleAdviseHolderImpl_SendOnClose
348 static HRESULT WINAPI
349 OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface)
351 ICOM_THIS(OleAdviseHolderImpl, iface);
352 FIXME("(%p)\n", This);
355 return S_OK;
358 /**************************************************************************
359 * DataAdviseHolder Implementation
361 typedef struct DataAdviseConnection {
362 IAdviseSink *sink;
363 FORMATETC fmat;
364 DWORD advf;
365 } DataAdviseConnection;
367 typedef struct DataAdviseHolder
369 ICOM_VFIELD(IDataAdviseHolder);
371 DWORD ref;
372 DWORD maxCons;
373 DataAdviseConnection* Connections;
374 } DataAdviseHolder;
376 /**************************************************************************
377 * DataAdviseHolder method prototypes
379 static IDataAdviseHolder* DataAdviseHolder_Constructor();
380 static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy);
381 static HRESULT WINAPI DataAdviseHolder_QueryInterface(
382 IDataAdviseHolder* iface,
383 REFIID riid,
384 void** ppvObject);
385 static ULONG WINAPI DataAdviseHolder_AddRef(
386 IDataAdviseHolder* iface);
387 static ULONG WINAPI DataAdviseHolder_Release(
388 IDataAdviseHolder* iface);
389 static HRESULT WINAPI DataAdviseHolder_Advise(
390 IDataAdviseHolder* iface,
391 IDataObject* pDataObject,
392 FORMATETC* pFetc,
393 DWORD advf,
394 IAdviseSink* pAdvise,
395 DWORD* pdwConnection);
396 static HRESULT WINAPI DataAdviseHolder_Unadvise(
397 IDataAdviseHolder* iface,
398 DWORD dwConnection);
399 static HRESULT WINAPI DataAdviseHolder_EnumAdvise(
400 IDataAdviseHolder* iface,
401 IEnumSTATDATA** ppenumAdvise);
402 static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
403 IDataAdviseHolder* iface,
404 IDataObject* pDataObject,
405 DWORD dwReserved,
406 DWORD advf);
408 /**************************************************************************
409 * DataAdviseHolderImpl_VTable
411 static struct ICOM_VTABLE(IDataAdviseHolder) DataAdviseHolderImpl_VTable =
413 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
414 DataAdviseHolder_QueryInterface,
415 DataAdviseHolder_AddRef,
416 DataAdviseHolder_Release,
417 DataAdviseHolder_Advise,
418 DataAdviseHolder_Unadvise,
419 DataAdviseHolder_EnumAdvise,
420 DataAdviseHolder_SendOnDataChange
423 /******************************************************************************
424 * DataAdviseHolder_Constructor
426 static IDataAdviseHolder* DataAdviseHolder_Constructor()
428 DataAdviseHolder* newHolder;
430 newHolder = (DataAdviseHolder*)HeapAlloc(GetProcessHeap(),
432 sizeof(DataAdviseHolder));
434 ICOM_VTBL(newHolder) = &DataAdviseHolderImpl_VTable;
435 newHolder->ref = 1;
436 newHolder->maxCons = INITIAL_SINKS;
437 newHolder->Connections = HeapAlloc(GetProcessHeap(),
438 HEAP_ZERO_MEMORY,
439 newHolder->maxCons *
440 sizeof(DataAdviseConnection));
442 TRACE("returning %p\n", newHolder);
443 return (IDataAdviseHolder*)newHolder;
446 /******************************************************************************
447 * DataAdviseHolder_Destructor
449 static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy)
451 DWORD index;
452 TRACE("%p\n", ptrToDestroy);
454 for (index = 0; index < ptrToDestroy->maxCons; index++)
456 if (ptrToDestroy->Connections[index].sink != NULL)
458 IAdviseSink_Release(ptrToDestroy->Connections[index].sink);
459 ptrToDestroy->Connections[index].sink = NULL;
463 HeapFree(GetProcessHeap(), 0, ptrToDestroy->Connections);
464 HeapFree(GetProcessHeap(), 0, ptrToDestroy);
467 /************************************************************************
468 * DataAdviseHolder_QueryInterface (IUnknown)
470 * See Windows documentation for more details on IUnknown methods.
472 static HRESULT WINAPI DataAdviseHolder_QueryInterface(
473 IDataAdviseHolder* iface,
474 REFIID riid,
475 void** ppvObject)
477 ICOM_THIS(DataAdviseHolder, iface);
478 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObject);
480 * Perform a sanity check on the parameters.
482 if ( (This==0) || (ppvObject==0) )
483 return E_INVALIDARG;
486 * Initialize the return parameter.
488 *ppvObject = 0;
491 * Compare the riid with the interface IDs implemented by this object.
493 if ( (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) ||
494 (memcmp(&IID_IDataAdviseHolder, riid, sizeof(IID_IDataAdviseHolder)) == 0) )
496 *ppvObject = iface;
500 * Check that we obtained an interface.
502 if ((*ppvObject)==0)
504 return E_NOINTERFACE;
508 * Query Interface always increases the reference count by one when it is
509 * successful.
511 IUnknown_AddRef((IUnknown*)*ppvObject);
513 return S_OK;
516 /************************************************************************
517 * DataAdviseHolder_AddRef (IUnknown)
519 * See Windows documentation for more details on IUnknown methods.
521 static ULONG WINAPI DataAdviseHolder_AddRef(
522 IDataAdviseHolder* iface)
524 ICOM_THIS(DataAdviseHolder, iface);
525 TRACE("(%p) (ref=%ld)\n", This, This->ref);
526 This->ref++;
528 return This->ref;
531 /************************************************************************
532 * DataAdviseHolder_Release (IUnknown)
534 * See Windows documentation for more details on IUnknown methods.
536 static ULONG WINAPI DataAdviseHolder_Release(
537 IDataAdviseHolder* iface)
539 ICOM_THIS(DataAdviseHolder, iface);
540 TRACE("(%p) (ref=%ld)\n", This, This->ref);
543 * Decrease the reference count on this object.
545 This->ref--;
548 * If the reference count goes down to 0, perform suicide.
550 if (This->ref==0)
552 DataAdviseHolder_Destructor(This);
554 return 0;
557 return This->ref;
560 /************************************************************************
561 * DataAdviseHolder_Advise
564 static HRESULT WINAPI DataAdviseHolder_Advise(
565 IDataAdviseHolder* iface,
566 IDataObject* pDataObject,
567 FORMATETC* pFetc,
568 DWORD advf,
569 IAdviseSink* pAdvise,
570 DWORD* pdwConnection)
572 DWORD index;
574 ICOM_THIS(DataAdviseHolder, iface);
576 TRACE("(%p)->(%p, %p, %08lx, %p, %p)\n", This, pDataObject, pFetc, advf,
577 pAdvise, pdwConnection);
579 * Sanity check
581 if (pdwConnection==NULL)
582 return E_POINTER;
584 *pdwConnection = 0;
587 * Find a free spot in the array.
589 for (index = 0; index < This->maxCons; index++)
591 if (This->Connections[index].sink == NULL)
592 break;
596 * If the array is full, we need to grow it.
598 if (index == This->maxCons)
600 This->maxCons+=INITIAL_SINKS;
601 This->Connections = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
602 This->Connections,
603 This->maxCons*sizeof(DataAdviseConnection));
606 * Store the new sink
608 This->Connections[index].sink = pAdvise;
609 memcpy(&(This->Connections[index].fmat), pFetc, sizeof(FORMATETC));
610 This->Connections[index].advf = advf;
612 if (This->Connections[index].sink != NULL) {
613 IAdviseSink_AddRef(This->Connections[index].sink);
614 if(advf & ADVF_PRIMEFIRST) {
615 DataAdviseHolder_SendOnDataChange(iface, pDataObject, 0, advf);
619 * Return the index as the cookie.
620 * Since 0 is not a valid cookie, we will increment by
621 * 1 the index in the table.
623 *pdwConnection = index+1;
625 return S_OK;
628 /******************************************************************************
629 * DataAdviseHolder_Unadvise
631 static HRESULT WINAPI DataAdviseHolder_Unadvise(
632 IDataAdviseHolder* iface,
633 DWORD dwConnection)
635 ICOM_THIS(DataAdviseHolder, iface);
637 TRACE("(%p)->(%lu)\n", This, dwConnection);
640 * So we don't return 0 as a cookie, the index was
641 * incremented by 1 in OleAdviseHolderImpl_Advise
642 * we have to compensate.
644 dwConnection--;
647 * Check for invalid cookies.
649 if (dwConnection >= This->maxCons)
650 return OLE_E_NOCONNECTION;
652 if (This->Connections[dwConnection].sink == NULL)
653 return OLE_E_NOCONNECTION;
656 * Release the sink and mark the spot in the list as free.
658 IAdviseSink_Release(This->Connections[dwConnection].sink);
659 memset(&(This->Connections[dwConnection]), 0, sizeof(DataAdviseConnection));
660 return S_OK;
663 static HRESULT WINAPI DataAdviseHolder_EnumAdvise(
664 IDataAdviseHolder* iface,
665 IEnumSTATDATA** ppenumAdvise)
667 ICOM_THIS(DataAdviseHolder, iface);
669 FIXME("(%p)->(%p)\n", This, ppenumAdvise);
670 return E_NOTIMPL;
673 /******************************************************************************
674 * DataAdviseHolder_SendOnDataChange
676 static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
677 IDataAdviseHolder* iface,
678 IDataObject* pDataObject,
679 DWORD dwReserved,
680 DWORD advf)
682 ICOM_THIS(DataAdviseHolder, iface);
683 DWORD index;
684 STGMEDIUM stg;
685 HRESULT res;
687 TRACE("(%p)->(%p,%08lx,%08lx)\n", This, pDataObject, dwReserved, advf);
689 for(index = 0; index < This->maxCons; index++) {
690 if(This->Connections[index].sink != NULL) {
691 if(!(This->Connections[index].advf & ADVF_NODATA)) {
692 TRACE("Calling IDataObject_GetData\n");
693 res = IDataObject_GetData(pDataObject,
694 &(This->Connections[index].fmat),
695 &stg);
696 TRACE("returns %08lx\n", res);
698 TRACE("Calling IAdviseSink_OnDataChange\n");
699 IAdviseSink_OnDataChange(This->Connections[index].sink,
700 &(This->Connections[index].fmat),
701 &stg);
702 TRACE("Done IAdviseSink_OnDataChange\n");
703 if(This->Connections[index].advf & ADVF_ONLYONCE) {
704 TRACE("Removing connection\n");
705 DataAdviseHolder_Unadvise(iface, index+1);
709 return S_OK;
712 /***********************************************************************
713 * API functions
716 /***********************************************************************
717 * CreateOleAdviseHolder [OLE32.59]
719 HRESULT WINAPI CreateOleAdviseHolder(
720 LPOLEADVISEHOLDER *ppOAHolder)
722 TRACE("(%p)\n", ppOAHolder);
725 * Sanity check,
727 if (ppOAHolder==NULL)
728 return E_POINTER;
730 *ppOAHolder = OleAdviseHolderImpl_Constructor ();
732 if (*ppOAHolder != NULL)
733 return S_OK;
735 return E_OUTOFMEMORY;
738 /******************************************************************************
739 * CreateDataAdviseHolder [OLE32.53]
741 HRESULT WINAPI CreateDataAdviseHolder(
742 LPDATAADVISEHOLDER* ppDAHolder)
744 TRACE("(%p)\n", ppDAHolder);
747 * Sanity check,
749 if (ppDAHolder==NULL)
750 return E_POINTER;
752 *ppDAHolder = DataAdviseHolder_Constructor();
754 if (*ppDAHolder != NULL)
755 return S_OK;
757 return E_OUTOFMEMORY;