HTTP_DealWithProxy: Only add http:// to proxy string when needed.
[wine/multimedia.git] / dlls / ole32 / oleobj.c
blobcced63a3066e82d4f702bff2394bf74692bd51fd
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 "winuser.h"
28 #include "winerror.h"
29 #include "wine/debug.h"
30 #include "ole2.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(ole);
34 #define INITIAL_SINKS 10
36 /**************************************************************************
37 * OleAdviseHolderImpl Implementation
39 typedef struct OleAdviseHolderImpl
41 ICOM_VFIELD(IOleAdviseHolder);
43 DWORD ref;
45 DWORD maxSinks;
46 IAdviseSink** arrayOfSinks;
48 } OleAdviseHolderImpl;
50 static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor();
51 static void OleAdviseHolderImpl_Destructor(OleAdviseHolderImpl* ptrToDestroy);
52 static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(LPOLEADVISEHOLDER,REFIID,LPVOID*);
53 static ULONG WINAPI OleAdviseHolderImpl_AddRef(LPOLEADVISEHOLDER);
54 static ULONG WINAPI OleAdviseHolderImpl_Release(LPOLEADVISEHOLDER);
55 static HRESULT WINAPI OleAdviseHolderImpl_Advise(LPOLEADVISEHOLDER, IAdviseSink*, DWORD*);
56 static HRESULT WINAPI OleAdviseHolderImpl_Unadvise (LPOLEADVISEHOLDER, DWORD);
57 static HRESULT WINAPI OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER, IEnumSTATDATA **);
58 static HRESULT WINAPI OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER, IMoniker *);
59 static HRESULT WINAPI OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER);
60 static HRESULT WINAPI OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER);
63 /**************************************************************************
64 * OleAdviseHolderImpl_VTable
66 static struct ICOM_VTABLE(IOleAdviseHolder) oahvt =
68 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
69 OleAdviseHolderImpl_QueryInterface,
70 OleAdviseHolderImpl_AddRef,
71 OleAdviseHolderImpl_Release,
72 OleAdviseHolderImpl_Advise,
73 OleAdviseHolderImpl_Unadvise,
74 OleAdviseHolderImpl_EnumAdvise,
75 OleAdviseHolderImpl_SendOnRename,
76 OleAdviseHolderImpl_SendOnSave,
77 OleAdviseHolderImpl_SendOnClose
80 /**************************************************************************
81 * OleAdviseHolderImpl_Constructor
84 static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor()
86 OleAdviseHolderImpl* lpoah;
87 DWORD index;
89 lpoah= (OleAdviseHolderImpl*)HeapAlloc(GetProcessHeap(),
91 sizeof(OleAdviseHolderImpl));
93 lpoah->lpVtbl = &oahvt;
94 lpoah->ref = 1;
95 lpoah->maxSinks = INITIAL_SINKS;
96 lpoah->arrayOfSinks = HeapAlloc(GetProcessHeap(),
98 lpoah->maxSinks * sizeof(IAdviseSink*));
100 for (index = 0; index < lpoah->maxSinks; index++)
101 lpoah->arrayOfSinks[index]=0;
103 TRACE("returning %p\n", lpoah);
104 return (LPOLEADVISEHOLDER)lpoah;
107 /**************************************************************************
108 * OleAdviseHolderImpl_Destructor
110 static void OleAdviseHolderImpl_Destructor(
111 OleAdviseHolderImpl* ptrToDestroy)
113 DWORD index;
114 TRACE("%p\n", ptrToDestroy);
116 for (index = 0; index < ptrToDestroy->maxSinks; index++)
118 if (ptrToDestroy->arrayOfSinks[index]!=0)
120 IAdviseSink_Release(ptrToDestroy->arrayOfSinks[index]);
121 ptrToDestroy->arrayOfSinks[index] = NULL;
125 HeapFree(GetProcessHeap(),
127 ptrToDestroy->arrayOfSinks);
130 HeapFree(GetProcessHeap(),
132 ptrToDestroy);
135 /**************************************************************************
136 * OleAdviseHolderImpl_QueryInterface
138 static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(
139 LPOLEADVISEHOLDER iface,
140 REFIID riid,
141 LPVOID* ppvObj)
143 ICOM_THIS(OleAdviseHolderImpl, iface);
144 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObj);
146 * Sanity check
148 if (ppvObj==NULL)
149 return E_POINTER;
151 *ppvObj = NULL;
153 if (IsEqualIID(riid, &IID_IUnknown))
155 /* IUnknown */
156 *ppvObj = This;
158 else if(IsEqualIID(riid, &IID_IOleAdviseHolder))
160 /* IOleAdviseHolder */
161 *ppvObj = (IOleAdviseHolder*) This;
164 if(*ppvObj == NULL)
165 return E_NOINTERFACE;
168 * A successful QI always increments the reference count.
170 IUnknown_AddRef((IUnknown*)*ppvObj);
172 return S_OK;
175 /******************************************************************************
176 * OleAdviseHolderImpl_AddRef
178 static ULONG WINAPI OleAdviseHolderImpl_AddRef(
179 LPOLEADVISEHOLDER iface)
181 ICOM_THIS(OleAdviseHolderImpl, iface);
182 TRACE("(%p)->(ref=%ld)\n", This, This->ref);
183 return ++(This->ref);
186 /******************************************************************************
187 * OleAdviseHolderImpl_Release
189 static ULONG WINAPI OleAdviseHolderImpl_Release(
190 LPOLEADVISEHOLDER iface)
192 ICOM_THIS(OleAdviseHolderImpl, iface);
193 TRACE("(%p)->(ref=%ld)\n", This, This->ref);
194 This->ref--;
196 if (This->ref == 0)
198 OleAdviseHolderImpl_Destructor(This);
200 return 0;
203 return This->ref;
206 /******************************************************************************
207 * OleAdviseHolderImpl_Advise
209 static HRESULT WINAPI OleAdviseHolderImpl_Advise(
210 LPOLEADVISEHOLDER iface,
211 IAdviseSink* pAdvise,
212 DWORD* pdwConnection)
214 DWORD index;
216 ICOM_THIS(OleAdviseHolderImpl, iface);
218 TRACE("(%p)->(%p, %p)\n", This, pAdvise, pdwConnection);
221 * Sanity check
223 if (pdwConnection==NULL)
224 return E_POINTER;
226 *pdwConnection = 0;
229 * Find a free spot in the array.
231 for (index = 0; index < This->maxSinks; index++)
233 if (This->arrayOfSinks[index]==NULL)
234 break;
238 * If the array is full, we need to grow it.
240 if (index == This->maxSinks)
242 DWORD i;
244 This->maxSinks+=INITIAL_SINKS;
246 This->arrayOfSinks = HeapReAlloc(GetProcessHeap(),
248 This->arrayOfSinks,
249 This->maxSinks*sizeof(IAdviseSink*));
251 for (i=index;i < This->maxSinks; i++)
252 This->arrayOfSinks[i]=0;
256 * Store the new sink
258 This->arrayOfSinks[index] = pAdvise;
260 if (This->arrayOfSinks[index]!=NULL)
261 IAdviseSink_AddRef(This->arrayOfSinks[index]);
264 * Return the index as the cookie.
265 * Since 0 is not a valid cookie, we will increment by
266 * 1 the index in the table.
268 *pdwConnection = index+1;
270 return S_OK;
273 /******************************************************************************
274 * OleAdviseHolderImpl_Unadvise
276 static HRESULT WINAPI OleAdviseHolderImpl_Unadvise(
277 LPOLEADVISEHOLDER iface,
278 DWORD dwConnection)
280 ICOM_THIS(OleAdviseHolderImpl, iface);
282 TRACE("(%p)->(%lu)\n", This, dwConnection);
285 * So we don't return 0 as a cookie, the index was
286 * incremented by 1 in OleAdviseHolderImpl_Advise
287 * we have to compensate.
289 dwConnection--;
292 * Check for invalid cookies.
294 if (dwConnection >= This->maxSinks)
295 return OLE_E_NOCONNECTION;
297 if (This->arrayOfSinks[dwConnection] == NULL)
298 return OLE_E_NOCONNECTION;
301 * Release the sink and mark the spot in the list as free.
303 IAdviseSink_Release(This->arrayOfSinks[dwConnection]);
304 This->arrayOfSinks[dwConnection] = NULL;
306 return S_OK;
309 /******************************************************************************
310 * OleAdviseHolderImpl_EnumAdvise
312 static HRESULT WINAPI
313 OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER iface, IEnumSTATDATA **ppenumAdvise)
315 ICOM_THIS(OleAdviseHolderImpl, iface);
316 FIXME("(%p)->(%p)\n", This, ppenumAdvise);
318 *ppenumAdvise = NULL;
320 return S_OK;
323 /******************************************************************************
324 * OleAdviseHolderImpl_SendOnRename
326 static HRESULT WINAPI
327 OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk)
329 ICOM_THIS(OleAdviseHolderImpl, iface);
330 FIXME("(%p)->(%p)\n", This, pmk);
333 return S_OK;
336 /******************************************************************************
337 * OleAdviseHolderImpl_SendOnSave
339 static HRESULT WINAPI
340 OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface)
342 ICOM_THIS(OleAdviseHolderImpl, iface);
343 FIXME("(%p)\n", This);
345 return S_OK;
348 /******************************************************************************
349 * OleAdviseHolderImpl_SendOnClose
351 static HRESULT WINAPI
352 OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface)
354 ICOM_THIS(OleAdviseHolderImpl, iface);
355 FIXME("(%p)\n", This);
358 return S_OK;
361 /**************************************************************************
362 * DataAdviseHolder Implementation
364 typedef struct DataAdviseConnection {
365 IAdviseSink *sink;
366 FORMATETC fmat;
367 DWORD advf;
368 } DataAdviseConnection;
370 typedef struct DataAdviseHolder
372 ICOM_VFIELD(IDataAdviseHolder);
374 DWORD ref;
375 DWORD maxCons;
376 DataAdviseConnection* Connections;
377 } DataAdviseHolder;
379 /**************************************************************************
380 * DataAdviseHolder method prototypes
382 static IDataAdviseHolder* DataAdviseHolder_Constructor();
383 static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy);
384 static HRESULT WINAPI DataAdviseHolder_QueryInterface(
385 IDataAdviseHolder* iface,
386 REFIID riid,
387 void** ppvObject);
388 static ULONG WINAPI DataAdviseHolder_AddRef(
389 IDataAdviseHolder* iface);
390 static ULONG WINAPI DataAdviseHolder_Release(
391 IDataAdviseHolder* iface);
392 static HRESULT WINAPI DataAdviseHolder_Advise(
393 IDataAdviseHolder* iface,
394 IDataObject* pDataObject,
395 FORMATETC* pFetc,
396 DWORD advf,
397 IAdviseSink* pAdvise,
398 DWORD* pdwConnection);
399 static HRESULT WINAPI DataAdviseHolder_Unadvise(
400 IDataAdviseHolder* iface,
401 DWORD dwConnection);
402 static HRESULT WINAPI DataAdviseHolder_EnumAdvise(
403 IDataAdviseHolder* iface,
404 IEnumSTATDATA** ppenumAdvise);
405 static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
406 IDataAdviseHolder* iface,
407 IDataObject* pDataObject,
408 DWORD dwReserved,
409 DWORD advf);
411 /**************************************************************************
412 * DataAdviseHolderImpl_VTable
414 static struct ICOM_VTABLE(IDataAdviseHolder) DataAdviseHolderImpl_VTable =
416 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
417 DataAdviseHolder_QueryInterface,
418 DataAdviseHolder_AddRef,
419 DataAdviseHolder_Release,
420 DataAdviseHolder_Advise,
421 DataAdviseHolder_Unadvise,
422 DataAdviseHolder_EnumAdvise,
423 DataAdviseHolder_SendOnDataChange
426 /******************************************************************************
427 * DataAdviseHolder_Constructor
429 static IDataAdviseHolder* DataAdviseHolder_Constructor()
431 DataAdviseHolder* newHolder;
433 newHolder = (DataAdviseHolder*)HeapAlloc(GetProcessHeap(),
435 sizeof(DataAdviseHolder));
437 newHolder->lpVtbl = &DataAdviseHolderImpl_VTable;
438 newHolder->ref = 1;
439 newHolder->maxCons = INITIAL_SINKS;
440 newHolder->Connections = HeapAlloc(GetProcessHeap(),
441 HEAP_ZERO_MEMORY,
442 newHolder->maxCons *
443 sizeof(DataAdviseConnection));
445 TRACE("returning %p\n", newHolder);
446 return (IDataAdviseHolder*)newHolder;
449 /******************************************************************************
450 * DataAdviseHolder_Destructor
452 static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy)
454 DWORD index;
455 TRACE("%p\n", ptrToDestroy);
457 for (index = 0; index < ptrToDestroy->maxCons; index++)
459 if (ptrToDestroy->Connections[index].sink != NULL)
461 IAdviseSink_Release(ptrToDestroy->Connections[index].sink);
462 ptrToDestroy->Connections[index].sink = NULL;
466 HeapFree(GetProcessHeap(), 0, ptrToDestroy->Connections);
467 HeapFree(GetProcessHeap(), 0, ptrToDestroy);
470 /************************************************************************
471 * DataAdviseHolder_QueryInterface (IUnknown)
473 * See Windows documentation for more details on IUnknown methods.
475 static HRESULT WINAPI DataAdviseHolder_QueryInterface(
476 IDataAdviseHolder* iface,
477 REFIID riid,
478 void** ppvObject)
480 ICOM_THIS(DataAdviseHolder, iface);
481 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObject);
483 * Perform a sanity check on the parameters.
485 if ( (This==0) || (ppvObject==0) )
486 return E_INVALIDARG;
489 * Initialize the return parameter.
491 *ppvObject = 0;
494 * Compare the riid with the interface IDs implemented by this object.
496 if ( (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) ||
497 (memcmp(&IID_IDataAdviseHolder, riid, sizeof(IID_IDataAdviseHolder)) == 0) )
499 *ppvObject = iface;
503 * Check that we obtained an interface.
505 if ((*ppvObject)==0)
507 return E_NOINTERFACE;
511 * Query Interface always increases the reference count by one when it is
512 * successful.
514 IUnknown_AddRef((IUnknown*)*ppvObject);
516 return S_OK;
519 /************************************************************************
520 * DataAdviseHolder_AddRef (IUnknown)
522 * See Windows documentation for more details on IUnknown methods.
524 static ULONG WINAPI DataAdviseHolder_AddRef(
525 IDataAdviseHolder* iface)
527 ICOM_THIS(DataAdviseHolder, iface);
528 TRACE("(%p) (ref=%ld)\n", This, This->ref);
529 This->ref++;
531 return This->ref;
534 /************************************************************************
535 * DataAdviseHolder_Release (IUnknown)
537 * See Windows documentation for more details on IUnknown methods.
539 static ULONG WINAPI DataAdviseHolder_Release(
540 IDataAdviseHolder* iface)
542 ICOM_THIS(DataAdviseHolder, iface);
543 TRACE("(%p) (ref=%ld)\n", This, This->ref);
546 * Decrease the reference count on this object.
548 This->ref--;
551 * If the reference count goes down to 0, perform suicide.
553 if (This->ref==0)
555 DataAdviseHolder_Destructor(This);
557 return 0;
560 return This->ref;
563 /************************************************************************
564 * DataAdviseHolder_Advise
567 static HRESULT WINAPI DataAdviseHolder_Advise(
568 IDataAdviseHolder* iface,
569 IDataObject* pDataObject,
570 FORMATETC* pFetc,
571 DWORD advf,
572 IAdviseSink* pAdvise,
573 DWORD* pdwConnection)
575 DWORD index;
577 ICOM_THIS(DataAdviseHolder, iface);
579 TRACE("(%p)->(%p, %p, %08lx, %p, %p)\n", This, pDataObject, pFetc, advf,
580 pAdvise, pdwConnection);
582 * Sanity check
584 if (pdwConnection==NULL)
585 return E_POINTER;
587 *pdwConnection = 0;
590 * Find a free spot in the array.
592 for (index = 0; index < This->maxCons; index++)
594 if (This->Connections[index].sink == NULL)
595 break;
599 * If the array is full, we need to grow it.
601 if (index == This->maxCons)
603 This->maxCons+=INITIAL_SINKS;
604 This->Connections = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
605 This->Connections,
606 This->maxCons*sizeof(DataAdviseConnection));
609 * Store the new sink
611 This->Connections[index].sink = pAdvise;
612 memcpy(&(This->Connections[index].fmat), pFetc, sizeof(FORMATETC));
613 This->Connections[index].advf = advf;
615 if (This->Connections[index].sink != NULL) {
616 IAdviseSink_AddRef(This->Connections[index].sink);
617 if(advf & ADVF_PRIMEFIRST) {
618 DataAdviseHolder_SendOnDataChange(iface, pDataObject, 0, advf);
622 * Return the index as the cookie.
623 * Since 0 is not a valid cookie, we will increment by
624 * 1 the index in the table.
626 *pdwConnection = index+1;
628 return S_OK;
631 /******************************************************************************
632 * DataAdviseHolder_Unadvise
634 static HRESULT WINAPI DataAdviseHolder_Unadvise(
635 IDataAdviseHolder* iface,
636 DWORD dwConnection)
638 ICOM_THIS(DataAdviseHolder, iface);
640 TRACE("(%p)->(%lu)\n", This, dwConnection);
643 * So we don't return 0 as a cookie, the index was
644 * incremented by 1 in OleAdviseHolderImpl_Advise
645 * we have to compensate.
647 dwConnection--;
650 * Check for invalid cookies.
652 if (dwConnection >= This->maxCons)
653 return OLE_E_NOCONNECTION;
655 if (This->Connections[dwConnection].sink == NULL)
656 return OLE_E_NOCONNECTION;
659 * Release the sink and mark the spot in the list as free.
661 IAdviseSink_Release(This->Connections[dwConnection].sink);
662 memset(&(This->Connections[dwConnection]), 0, sizeof(DataAdviseConnection));
663 return S_OK;
666 static HRESULT WINAPI DataAdviseHolder_EnumAdvise(
667 IDataAdviseHolder* iface,
668 IEnumSTATDATA** ppenumAdvise)
670 ICOM_THIS(DataAdviseHolder, iface);
672 FIXME("(%p)->(%p)\n", This, ppenumAdvise);
673 return E_NOTIMPL;
676 /******************************************************************************
677 * DataAdviseHolder_SendOnDataChange
679 static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
680 IDataAdviseHolder* iface,
681 IDataObject* pDataObject,
682 DWORD dwReserved,
683 DWORD advf)
685 ICOM_THIS(DataAdviseHolder, iface);
686 DWORD index;
687 STGMEDIUM stg;
688 HRESULT res;
690 TRACE("(%p)->(%p,%08lx,%08lx)\n", This, pDataObject, dwReserved, advf);
692 for(index = 0; index < This->maxCons; index++) {
693 if(This->Connections[index].sink != NULL) {
694 if(!(This->Connections[index].advf & ADVF_NODATA)) {
695 TRACE("Calling IDataObject_GetData\n");
696 res = IDataObject_GetData(pDataObject,
697 &(This->Connections[index].fmat),
698 &stg);
699 TRACE("returns %08lx\n", res);
701 TRACE("Calling IAdviseSink_OnDataChange\n");
702 IAdviseSink_OnDataChange(This->Connections[index].sink,
703 &(This->Connections[index].fmat),
704 &stg);
705 TRACE("Done IAdviseSink_OnDataChange\n");
706 if(This->Connections[index].advf & ADVF_ONLYONCE) {
707 TRACE("Removing connection\n");
708 DataAdviseHolder_Unadvise(iface, index+1);
712 return S_OK;
715 /***********************************************************************
716 * API functions
719 /***********************************************************************
720 * CreateOleAdviseHolder [OLE32.@]
722 HRESULT WINAPI CreateOleAdviseHolder(
723 LPOLEADVISEHOLDER *ppOAHolder)
725 TRACE("(%p)\n", ppOAHolder);
728 * Sanity check,
730 if (ppOAHolder==NULL)
731 return E_POINTER;
733 *ppOAHolder = OleAdviseHolderImpl_Constructor ();
735 if (*ppOAHolder != NULL)
736 return S_OK;
738 return E_OUTOFMEMORY;
741 /******************************************************************************
742 * CreateDataAdviseHolder [OLE32.@]
744 HRESULT WINAPI CreateDataAdviseHolder(
745 LPDATAADVISEHOLDER* ppDAHolder)
747 TRACE("(%p)\n", ppDAHolder);
750 * Sanity check,
752 if (ppDAHolder==NULL)
753 return E_POINTER;
755 *ppDAHolder = DataAdviseHolder_Constructor();
757 if (*ppDAHolder != NULL)
758 return S_OK;
760 return E_OUTOFMEMORY;