Check for busy DCE moved to DCHook16().
[wine/hacks.git] / ole / oleobj.c
blob63cf2e857046dc17a15ac2b7093f4b7350791cc5
1 /*
2 * OLE2 COM objects
4 * Copyright 1998 Eric Kohl
5 * Copyright 1999 Francis Beaudet
6 */
9 #include <string.h>
10 #include "winbase.h"
11 #include "winerror.h"
12 #include "oleidl.h"
13 #include "debug.h"
15 DEFAULT_DEBUG_CHANNEL(ole)
18 /**************************************************************************
19 * OleAdviseHolderImpl Implementation
21 typedef struct OleAdviseHolderImpl
23 ICOM_VTABLE(IOleAdviseHolder)* lpvtbl;
25 DWORD ref;
27 DWORD maxSinks;
28 IAdviseSink** arrayOfSinks;
30 } OleAdviseHolderImpl;
32 static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor();
33 static void OleAdviseHolderImpl_Destructor(OleAdviseHolderImpl* ptrToDestroy);
34 static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(LPOLEADVISEHOLDER,REFIID,LPVOID*);
35 static ULONG WINAPI OleAdviseHolderImpl_AddRef(LPOLEADVISEHOLDER);
36 static ULONG WINAPI OleAdviseHolderImpl_Release(LPOLEADVISEHOLDER);
37 static HRESULT WINAPI OleAdviseHolderImpl_Advise(LPOLEADVISEHOLDER, IAdviseSink*, DWORD*);
38 static HRESULT WINAPI OleAdviseHolderImpl_Unadvise (LPOLEADVISEHOLDER, DWORD);
39 static HRESULT WINAPI OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER, IEnumSTATDATA **);
40 static HRESULT WINAPI OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER, IMoniker *);
41 static HRESULT WINAPI OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER);
42 static HRESULT WINAPI OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER);
45 /**************************************************************************
46 * OleAdviseHolderImpl_VTable
48 static struct ICOM_VTABLE(IOleAdviseHolder) oahvt =
50 OleAdviseHolderImpl_QueryInterface,
51 OleAdviseHolderImpl_AddRef,
52 OleAdviseHolderImpl_Release,
53 OleAdviseHolderImpl_Advise,
54 OleAdviseHolderImpl_Unadvise,
55 OleAdviseHolderImpl_EnumAdvise,
56 OleAdviseHolderImpl_SendOnRename,
57 OleAdviseHolderImpl_SendOnSave,
58 OleAdviseHolderImpl_SendOnClose
61 /**************************************************************************
62 * OleAdviseHolderImpl_Constructor
65 static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor()
67 OleAdviseHolderImpl* lpoah;
68 DWORD index;
70 lpoah= (OleAdviseHolderImpl*)HeapAlloc(GetProcessHeap(),
72 sizeof(OleAdviseHolderImpl));
74 lpoah->lpvtbl = &oahvt;
75 lpoah->ref = 1;
76 lpoah->maxSinks = 10;
77 lpoah->arrayOfSinks = HeapAlloc(GetProcessHeap(),
79 lpoah->maxSinks * sizeof(IAdviseSink*));
81 for (index = 0; index < lpoah->maxSinks; index++)
82 lpoah->arrayOfSinks[index]=0;
84 return (LPOLEADVISEHOLDER)lpoah;
87 /**************************************************************************
88 * OleAdviseHolderImpl_Destructor
90 static void OleAdviseHolderImpl_Destructor(
91 OleAdviseHolderImpl* ptrToDestroy)
93 DWORD index;
95 for (index = 0; index < ptrToDestroy->maxSinks; index++)
97 if (ptrToDestroy->arrayOfSinks[index]!=0)
99 IAdviseSink_Release(ptrToDestroy->arrayOfSinks[index]);
100 ptrToDestroy->arrayOfSinks[index] = NULL;
104 HeapFree(GetProcessHeap(),
106 ptrToDestroy->arrayOfSinks);
109 HeapFree(GetProcessHeap(),
111 ptrToDestroy);
114 /**************************************************************************
115 * OleAdviseHolderImpl_QueryInterface
117 static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(
118 LPOLEADVISEHOLDER iface,
119 REFIID riid,
120 LPVOID* ppvObj)
122 ICOM_THIS(OleAdviseHolderImpl, iface);
125 * Sanity check
127 if (ppvObj==NULL)
128 return E_POINTER;
130 *ppvObj = NULL;
132 if (IsEqualIID(riid, &IID_IUnknown))
134 /* IUnknown */
135 *ppvObj = This;
137 else if(IsEqualIID(riid, &IID_IOleAdviseHolder))
139 /* IOleAdviseHolder */
140 *ppvObj = (IOleAdviseHolder*) This;
143 if(*ppvObj == NULL)
144 return E_NOINTERFACE;
147 * A successful QI always increments the reference count.
149 IUnknown_AddRef((IUnknown*)*ppvObj);
151 return S_OK;
154 /******************************************************************************
155 * OleAdviseHolderImpl_AddRef
157 static ULONG WINAPI OleAdviseHolderImpl_AddRef(
158 LPOLEADVISEHOLDER iface)
160 ICOM_THIS(OleAdviseHolderImpl, iface);
162 return ++(This->ref);
165 /******************************************************************************
166 * OleAdviseHolderImpl_Release
168 static ULONG WINAPI OleAdviseHolderImpl_Release(
169 LPOLEADVISEHOLDER iface)
171 ICOM_THIS(OleAdviseHolderImpl, iface);
173 This->ref--;
175 if (This->ref == 0)
177 OleAdviseHolderImpl_Destructor(This);
179 return 0;
182 return This->ref;
185 /******************************************************************************
186 * OleAdviseHolderImpl_Advise
188 static HRESULT WINAPI OleAdviseHolderImpl_Advise(
189 LPOLEADVISEHOLDER iface,
190 IAdviseSink* pAdvise,
191 DWORD* pdwConnection)
193 DWORD index;
195 ICOM_THIS(OleAdviseHolderImpl, iface);
197 TRACE(ole, "(%p, %p, %p)\n", This, pAdvise, pdwConnection);
200 * Sanity check
202 if (pdwConnection==NULL)
203 return E_POINTER;
205 *pdwConnection = 0;
208 * Find a free spot in the array.
210 for (index = 0; index < This->maxSinks; index++)
212 if (This->arrayOfSinks[index]==NULL)
213 break;
217 * If the array is full, we need to grow it.
219 if (index == This->maxSinks)
221 DWORD i;
223 This->maxSinks+=10;
225 This->arrayOfSinks = HeapReAlloc(GetProcessHeap(),
227 This->arrayOfSinks,
228 This->maxSinks*sizeof(IAdviseSink*));
230 for (i=index;i < This->maxSinks; i++)
231 This->arrayOfSinks[i]=0;
235 * Store the new sink
237 This->arrayOfSinks[index] = pAdvise;
239 if (This->arrayOfSinks[index]!=NULL)
240 IAdviseSink_AddRef(This->arrayOfSinks[index]);
243 * Return the index as the cookie.
245 *pdwConnection = index;
247 return S_OK;
250 /******************************************************************************
251 * OleAdviseHolderImpl_Unadvise
253 static HRESULT WINAPI OleAdviseHolderImpl_Unadvise(
254 LPOLEADVISEHOLDER iface,
255 DWORD dwConnection)
257 ICOM_THIS(OleAdviseHolderImpl, iface);
259 TRACE(ole, "(%p, %lu)\n", This, dwConnection);
262 * Check for invalid cookies.
264 if (dwConnection >= This->maxSinks)
265 return OLE_E_NOCONNECTION;
267 if (This->arrayOfSinks[dwConnection] == NULL)
268 return OLE_E_NOCONNECTION;
271 * Release the sink and mark the spot in the list as free.
273 IAdviseSink_Release(This->arrayOfSinks[dwConnection]);
274 This->arrayOfSinks[dwConnection] = NULL;
276 return S_OK;
279 /******************************************************************************
280 * OleAdviseHolderImpl_EnumAdvise
282 static HRESULT WINAPI
283 OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER iface, IEnumSTATDATA **ppenumAdvise)
285 ICOM_THIS(OleAdviseHolderImpl, iface);
286 FIXME (ole, "(%p)->(%p)\n", This, ppenumAdvise);
288 *ppenumAdvise = NULL;
290 return S_OK;
293 /******************************************************************************
294 * OleAdviseHolderImpl_SendOnRename
296 static HRESULT WINAPI
297 OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk)
299 ICOM_THIS(OleAdviseHolderImpl, iface);
300 FIXME (ole, "(%p)->(%p)\n", This, pmk);
303 return S_OK;
306 /******************************************************************************
307 * OleAdviseHolderImpl_SendOnSave
309 static HRESULT WINAPI
310 OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface)
312 ICOM_THIS(OleAdviseHolderImpl, iface);
313 FIXME (ole, "(%p)\n", This);
316 return S_OK;
319 /******************************************************************************
320 * OleAdviseHolderImpl_SendOnClose
322 static HRESULT WINAPI
323 OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface)
325 ICOM_THIS(OleAdviseHolderImpl, iface);
326 FIXME (ole, "(%p)\n", This);
329 return S_OK;
332 /**************************************************************************
333 * DataAdviseHolder Implementation
335 typedef struct DataAdviseHolder
337 ICOM_VTABLE(IDataAdviseHolder)* lpvtbl;
339 DWORD ref;
340 } DataAdviseHolder;
342 /**************************************************************************
343 * DataAdviseHolder method prototypes
345 static IDataAdviseHolder* DataAdviseHolder_Constructor();
346 static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy);
347 static HRESULT WINAPI DataAdviseHolder_QueryInterface(
348 IDataAdviseHolder* iface,
349 REFIID riid,
350 void** ppvObject);
351 static ULONG WINAPI DataAdviseHolder_AddRef(
352 IDataAdviseHolder* iface);
353 static ULONG WINAPI DataAdviseHolder_Release(
354 IDataAdviseHolder* iface);
355 static HRESULT WINAPI DataAdviseHolder_Advise(
356 IDataAdviseHolder* iface,
357 IDataObject* pDataObject,
358 FORMATETC* pFetc,
359 DWORD advf,
360 IAdviseSink* pAdvise,
361 DWORD* pdwConnection);
362 static HRESULT WINAPI DataAdviseHolder_Unadvise(
363 IDataAdviseHolder* iface,
364 DWORD dwConnection);
365 static HRESULT WINAPI DataAdviseHolder_EnumAdvise(
366 IDataAdviseHolder* iface,
367 IEnumSTATDATA** ppenumAdvise);
368 static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
369 IDataAdviseHolder* iface,
370 IDataObject* pDataObject,
371 DWORD dwReserved,
372 DWORD advf);
374 /**************************************************************************
375 * DataAdviseHolderImpl_VTable
377 static struct ICOM_VTABLE(IDataAdviseHolder) DataAdviseHolderImpl_VTable =
379 DataAdviseHolder_QueryInterface,
380 DataAdviseHolder_AddRef,
381 DataAdviseHolder_Release,
382 DataAdviseHolder_Advise,
383 DataAdviseHolder_Unadvise,
384 DataAdviseHolder_EnumAdvise,
385 DataAdviseHolder_SendOnDataChange
388 /******************************************************************************
389 * DataAdviseHolder_Constructor
391 static IDataAdviseHolder* DataAdviseHolder_Constructor()
393 DataAdviseHolder* newHolder;
395 newHolder = (DataAdviseHolder*)HeapAlloc(GetProcessHeap(),
397 sizeof(DataAdviseHolder));
399 newHolder->lpvtbl = &DataAdviseHolderImpl_VTable;
400 newHolder->ref = 1;
402 return (IDataAdviseHolder*)newHolder;
405 /******************************************************************************
406 * DataAdviseHolder_Destructor
408 static void DataAdviseHolder_Destructor(
409 DataAdviseHolder* ptrToDestroy)
411 HeapFree(GetProcessHeap(),
413 ptrToDestroy);
416 /************************************************************************
417 * DataAdviseHolder_QueryInterface (IUnknown)
419 * See Windows documentation for more details on IUnknown methods.
421 static HRESULT WINAPI DataAdviseHolder_QueryInterface(
422 IDataAdviseHolder* iface,
423 REFIID riid,
424 void** ppvObject)
426 ICOM_THIS(DataAdviseHolder, iface);
429 * Perform a sanity check on the parameters.
431 if ( (This==0) || (ppvObject==0) )
432 return E_INVALIDARG;
435 * Initialize the return parameter.
437 *ppvObject = 0;
440 * Compare the riid with the interface IDs implemented by this object.
442 if ( (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) ||
443 (memcmp(&IID_IDataAdviseHolder, riid, sizeof(IID_IDataAdviseHolder)) == 0) )
445 *ppvObject = iface;
449 * Check that we obtained an interface.
451 if ((*ppvObject)==0)
453 return E_NOINTERFACE;
457 * Query Interface always increases the reference count by one when it is
458 * successful.
460 IUnknown_AddRef((IUnknown*)*ppvObject);
462 return S_OK;;
465 /************************************************************************
466 * DataAdviseHolder_AddRef (IUnknown)
468 * See Windows documentation for more details on IUnknown methods.
470 static ULONG WINAPI DataAdviseHolder_AddRef(
471 IDataAdviseHolder* iface)
473 ICOM_THIS(DataAdviseHolder, iface);
475 This->ref++;
477 return This->ref;
480 /************************************************************************
481 * DataAdviseHolder_Release (IUnknown)
483 * See Windows documentation for more details on IUnknown methods.
485 static ULONG WINAPI DataAdviseHolder_Release(
486 IDataAdviseHolder* iface)
488 ICOM_THIS(DataAdviseHolder, iface);
491 * Decrease the reference count on this object.
493 This->ref--;
496 * If the reference count goes down to 0, perform suicide.
498 if (This->ref==0)
500 DataAdviseHolder_Destructor(This);
502 return 0;
505 return This->ref;
508 static HRESULT WINAPI DataAdviseHolder_Advise(
509 IDataAdviseHolder* iface,
510 IDataObject* pDataObject,
511 FORMATETC* pFetc,
512 DWORD advf,
513 IAdviseSink* pAdvise,
514 DWORD* pdwConnection)
516 FIXME(ole, "(): stub\n");
517 return E_NOTIMPL;
520 static HRESULT WINAPI DataAdviseHolder_Unadvise(
521 IDataAdviseHolder* iface,
522 DWORD dwConnection)
524 FIXME(ole, "(): stub\n");
525 return E_NOTIMPL;
528 static HRESULT WINAPI DataAdviseHolder_EnumAdvise(
529 IDataAdviseHolder* iface,
530 IEnumSTATDATA** ppenumAdvise)
532 FIXME(ole, "(): stub\n");
533 return E_NOTIMPL;
536 static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
537 IDataAdviseHolder* iface,
538 IDataObject* pDataObject,
539 DWORD dwReserved,
540 DWORD advf)
542 FIXME(ole, "(): stub\n");
543 return E_NOTIMPL;
546 /***********************************************************************
547 * API functions
550 /***********************************************************************
551 * CreateOleAdviseHolder [OLE32.59]
553 HRESULT WINAPI CreateOleAdviseHolder(
554 LPOLEADVISEHOLDER *ppOAHolder)
556 TRACE(ole, "(%p)\n", ppOAHolder);
559 * Sanity check,
561 if (ppOAHolder==NULL)
562 return E_POINTER;
564 *ppOAHolder = OleAdviseHolderImpl_Constructor ();
566 if (*ppOAHolder != NULL)
567 return S_OK;
569 return E_OUTOFMEMORY;
572 /******************************************************************************
573 * CreateDataAdviseHolder [OLE32.53]
575 HRESULT WINAPI CreateDataAdviseHolder(
576 LPDATAADVISEHOLDER* ppDAHolder)
578 TRACE(ole,"(%p)\n", ppDAHolder);
581 * Sanity check,
583 if (ppDAHolder==NULL)
584 return E_POINTER;
586 *ppDAHolder = DataAdviseHolder_Constructor();
588 if (*ppDAHolder != NULL)
589 return S_OK;
591 return E_OUTOFMEMORY;