source: trunk/src/ole32/oleobj.c@ 7508

Last change on this file since 7508 was 7508, checked in by sandervl, 24 years ago

removed TRACE/WARN macro redefinition

File size: 18.9 KB
Line 
1/*
2 * OLE2 COM objects
3 *
4 * Copyright 1998 Eric Kohl
5 * Copyright 1999 Francis Beaudet
6 */
7
8
9#include <string.h>
10#include "winbase.h"
11#include "winerror.h"
12#include "debugtools.h"
13#include "oleidl.h"
14
15DEFAULT_DEBUG_CHANNEL(ole);
16
17#define INITIAL_SINKS 10
18
19/**************************************************************************
20 * OleAdviseHolderImpl Implementation
21 */
22typedef struct OleAdviseHolderImpl
23{
24 ICOM_VFIELD(IOleAdviseHolder);
25
26 DWORD ref;
27
28 DWORD maxSinks;
29 IAdviseSink** arrayOfSinks;
30
31} OleAdviseHolderImpl;
32
33static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor();
34static void OleAdviseHolderImpl_Destructor(OleAdviseHolderImpl* ptrToDestroy);
35static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(LPOLEADVISEHOLDER,REFIID,LPVOID*);
36static ULONG WINAPI OleAdviseHolderImpl_AddRef(LPOLEADVISEHOLDER);
37static ULONG WINAPI OleAdviseHolderImpl_Release(LPOLEADVISEHOLDER);
38static HRESULT WINAPI OleAdviseHolderImpl_Advise(LPOLEADVISEHOLDER, IAdviseSink*, DWORD*);
39static HRESULT WINAPI OleAdviseHolderImpl_Unadvise (LPOLEADVISEHOLDER, DWORD);
40static HRESULT WINAPI OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER, IEnumSTATDATA **);
41static HRESULT WINAPI OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER, IMoniker *);
42static HRESULT WINAPI OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER);
43static HRESULT WINAPI OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER);
44
45
46/**************************************************************************
47 * OleAdviseHolderImpl_VTable
48 */
49static struct ICOM_VTABLE(IOleAdviseHolder) oahvt =
50{
51 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
52 OleAdviseHolderImpl_QueryInterface,
53 OleAdviseHolderImpl_AddRef,
54 OleAdviseHolderImpl_Release,
55 OleAdviseHolderImpl_Advise,
56 OleAdviseHolderImpl_Unadvise,
57 OleAdviseHolderImpl_EnumAdvise,
58 OleAdviseHolderImpl_SendOnRename,
59 OleAdviseHolderImpl_SendOnSave,
60 OleAdviseHolderImpl_SendOnClose
61};
62
63/**************************************************************************
64 * OleAdviseHolderImpl_Constructor
65 */
66
67static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor()
68{
69 OleAdviseHolderImpl* lpoah;
70 DWORD index;
71
72 lpoah= (OleAdviseHolderImpl*)HeapAlloc(GetProcessHeap(),
73 0,
74 sizeof(OleAdviseHolderImpl));
75
76 ICOM_VTBL(lpoah) = &oahvt;
77 lpoah->ref = 1;
78 lpoah->maxSinks = INITIAL_SINKS;
79 lpoah->arrayOfSinks = HeapAlloc(GetProcessHeap(),
80 0,
81 lpoah->maxSinks * sizeof(IAdviseSink*));
82
83 for (index = 0; index < lpoah->maxSinks; index++)
84 lpoah->arrayOfSinks[index]=0;
85
86 TRACE("returning %p\n", lpoah);
87 return (LPOLEADVISEHOLDER)lpoah;
88}
89
90/**************************************************************************
91 * OleAdviseHolderImpl_Destructor
92 */
93static void OleAdviseHolderImpl_Destructor(
94 OleAdviseHolderImpl* ptrToDestroy)
95{
96 DWORD index;
97 TRACE("%p\n", ptrToDestroy);
98
99 for (index = 0; index < ptrToDestroy->maxSinks; index++)
100 {
101 if (ptrToDestroy->arrayOfSinks[index]!=0)
102 {
103 IAdviseSink_Release(ptrToDestroy->arrayOfSinks[index]);
104 ptrToDestroy->arrayOfSinks[index] = NULL;
105 }
106 }
107
108 HeapFree(GetProcessHeap(),
109 0,
110 ptrToDestroy->arrayOfSinks);
111
112
113 HeapFree(GetProcessHeap(),
114 0,
115 ptrToDestroy);
116}
117
118/**************************************************************************
119 * OleAdviseHolderImpl_QueryInterface
120 */
121static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(
122 LPOLEADVISEHOLDER iface,
123 REFIID riid,
124 LPVOID* ppvObj)
125{
126 ICOM_THIS(OleAdviseHolderImpl, iface);
127 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObj);
128 /*
129 * Sanity check
130 */
131 if (ppvObj==NULL)
132 return E_POINTER;
133
134 *ppvObj = NULL;
135
136 if (IsEqualIID(riid, &IID_IUnknown))
137 {
138 /* IUnknown */
139 *ppvObj = This;
140 }
141 else if(IsEqualIID(riid, &IID_IOleAdviseHolder))
142 {
143 /* IOleAdviseHolder */
144 *ppvObj = (IOleAdviseHolder*) This;
145 }
146
147 if(*ppvObj == NULL)
148 return E_NOINTERFACE;
149
150 /*
151 * A successful QI always increments the reference count.
152 */
153 IUnknown_AddRef((IUnknown*)*ppvObj);
154
155 return S_OK;
156}
157
158/******************************************************************************
159 * OleAdviseHolderImpl_AddRef
160 */
161static ULONG WINAPI OleAdviseHolderImpl_AddRef(
162 LPOLEADVISEHOLDER iface)
163{
164 ICOM_THIS(OleAdviseHolderImpl, iface);
165 TRACE("(%p)->(ref=%ld)\n", This, This->ref);
166 return ++(This->ref);
167}
168
169/******************************************************************************
170 * OleAdviseHolderImpl_Release
171 */
172static ULONG WINAPI OleAdviseHolderImpl_Release(
173 LPOLEADVISEHOLDER iface)
174{
175 ICOM_THIS(OleAdviseHolderImpl, iface);
176 TRACE("(%p)->(ref=%ld)\n", This, This->ref);
177 This->ref--;
178
179 if (This->ref == 0)
180 {
181 OleAdviseHolderImpl_Destructor(This);
182
183 return 0;
184 }
185
186 return This->ref;
187}
188
189/******************************************************************************
190 * OleAdviseHolderImpl_Advise
191 */
192static HRESULT WINAPI OleAdviseHolderImpl_Advise(
193 LPOLEADVISEHOLDER iface,
194 IAdviseSink* pAdvise,
195 DWORD* pdwConnection)
196{
197 DWORD index;
198
199 ICOM_THIS(OleAdviseHolderImpl, iface);
200
201 TRACE("(%p)->(%p, %p)\n", This, pAdvise, pdwConnection);
202
203 /*
204 * Sanity check
205 */
206 if (pdwConnection==NULL)
207 return E_POINTER;
208
209 *pdwConnection = 0;
210
211 /*
212 * Find a free spot in the array.
213 */
214 for (index = 0; index < This->maxSinks; index++)
215 {
216 if (This->arrayOfSinks[index]==NULL)
217 break;
218 }
219
220 /*
221 * If the array is full, we need to grow it.
222 */
223 if (index == This->maxSinks)
224 {
225 DWORD i;
226
227 This->maxSinks+=INITIAL_SINKS;
228
229 This->arrayOfSinks = HeapReAlloc(GetProcessHeap(),
230 0,
231 This->arrayOfSinks,
232 This->maxSinks*sizeof(IAdviseSink*));
233
234 for (i=index;i < This->maxSinks; i++)
235 This->arrayOfSinks[i]=0;
236 }
237
238 /*
239 * Store the new sink
240 */
241 This->arrayOfSinks[index] = pAdvise;
242
243 if (This->arrayOfSinks[index]!=NULL)
244 IAdviseSink_AddRef(This->arrayOfSinks[index]);
245
246 /*
247 * Return the index as the cookie.
248 * Since 0 is not a valid cookie, we will increment by
249 * 1 the index in the table.
250 */
251 *pdwConnection = index+1;
252
253 return S_OK;
254}
255
256/******************************************************************************
257 * OleAdviseHolderImpl_Unadvise
258 */
259static HRESULT WINAPI OleAdviseHolderImpl_Unadvise(
260 LPOLEADVISEHOLDER iface,
261 DWORD dwConnection)
262{
263 ICOM_THIS(OleAdviseHolderImpl, iface);
264
265 TRACE("(%p)->(%lu)\n", This, dwConnection);
266
267 /*
268 * So we don't return 0 as a cookie, the index was
269 * incremented by 1 in OleAdviseHolderImpl_Advise
270 * we have to compensate.
271 */
272 dwConnection--;
273
274 /*
275 * Check for invalid cookies.
276 */
277 if ( (dwConnection < 0) ||
278 (dwConnection >= This->maxSinks) )
279 return OLE_E_NOCONNECTION;
280
281 if (This->arrayOfSinks[dwConnection] == NULL)
282 return OLE_E_NOCONNECTION;
283
284 /*
285 * Release the sink and mark the spot in the list as free.
286 */
287 IAdviseSink_Release(This->arrayOfSinks[dwConnection]);
288 This->arrayOfSinks[dwConnection] = NULL;
289
290 return S_OK;
291}
292
293/******************************************************************************
294 * OleAdviseHolderImpl_EnumAdvise
295 */
296static HRESULT WINAPI
297OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER iface, IEnumSTATDATA **ppenumAdvise)
298{
299 ICOM_THIS(OleAdviseHolderImpl, iface);
300 FIXME("(%p)->(%p)\n", This, ppenumAdvise);
301
302 *ppenumAdvise = NULL;
303
304 return S_OK;
305}
306
307/******************************************************************************
308 * OleAdviseHolderImpl_SendOnRename
309 */
310static HRESULT WINAPI
311OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk)
312{
313 ICOM_THIS(OleAdviseHolderImpl, iface);
314 FIXME("(%p)->(%p)\n", This, pmk);
315
316
317 return S_OK;
318}
319
320/******************************************************************************
321 * OleAdviseHolderImpl_SendOnSave
322 */
323static HRESULT WINAPI
324OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface)
325{
326 ICOM_THIS(OleAdviseHolderImpl, iface);
327 FIXME("(%p)\n", This);
328
329 return S_OK;
330}
331
332/******************************************************************************
333 * OleAdviseHolderImpl_SendOnClose
334 */
335static HRESULT WINAPI
336OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface)
337{
338 ICOM_THIS(OleAdviseHolderImpl, iface);
339 FIXME("(%p)\n", This);
340
341
342 return S_OK;
343}
344
345/**************************************************************************
346 * DataAdviseHolder Implementation
347 */
348typedef struct DataAdviseConnection {
349 IAdviseSink *sink;
350 FORMATETC fmat;
351 DWORD advf;
352} DataAdviseConnection;
353
354typedef struct DataAdviseHolder
355{
356 ICOM_VFIELD(IDataAdviseHolder);
357
358 DWORD ref;
359 DWORD maxCons;
360 DataAdviseConnection* Connections;
361} DataAdviseHolder;
362
363/**************************************************************************
364 * DataAdviseHolder method prototypes
365 */
366static IDataAdviseHolder* DataAdviseHolder_Constructor();
367static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy);
368static HRESULT WINAPI DataAdviseHolder_QueryInterface(
369 IDataAdviseHolder* iface,
370 REFIID riid,
371 void** ppvObject);
372static ULONG WINAPI DataAdviseHolder_AddRef(
373 IDataAdviseHolder* iface);
374static ULONG WINAPI DataAdviseHolder_Release(
375 IDataAdviseHolder* iface);
376static HRESULT WINAPI DataAdviseHolder_Advise(
377 IDataAdviseHolder* iface,
378 IDataObject* pDataObject,
379 FORMATETC* pFetc,
380 DWORD advf,
381 IAdviseSink* pAdvise,
382 DWORD* pdwConnection);
383static HRESULT WINAPI DataAdviseHolder_Unadvise(
384 IDataAdviseHolder* iface,
385 DWORD dwConnection);
386static HRESULT WINAPI DataAdviseHolder_EnumAdvise(
387 IDataAdviseHolder* iface,
388 IEnumSTATDATA** ppenumAdvise);
389static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
390 IDataAdviseHolder* iface,
391 IDataObject* pDataObject,
392 DWORD dwReserved,
393 DWORD advf);
394
395/**************************************************************************
396 * DataAdviseHolderImpl_VTable
397 */
398static struct ICOM_VTABLE(IDataAdviseHolder) DataAdviseHolderImpl_VTable =
399{
400 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
401 DataAdviseHolder_QueryInterface,
402 DataAdviseHolder_AddRef,
403 DataAdviseHolder_Release,
404 DataAdviseHolder_Advise,
405 DataAdviseHolder_Unadvise,
406 DataAdviseHolder_EnumAdvise,
407 DataAdviseHolder_SendOnDataChange
408};
409
410/******************************************************************************
411 * DataAdviseHolder_Constructor
412 */
413static IDataAdviseHolder* DataAdviseHolder_Constructor()
414{
415 DataAdviseHolder* newHolder;
416
417 newHolder = (DataAdviseHolder*)HeapAlloc(GetProcessHeap(),
418 0,
419 sizeof(DataAdviseHolder));
420
421 ICOM_VTBL(newHolder) = &DataAdviseHolderImpl_VTable;
422 newHolder->ref = 1;
423 newHolder->maxCons = INITIAL_SINKS;
424 newHolder->Connections = HeapAlloc(GetProcessHeap(),
425 HEAP_ZERO_MEMORY,
426 newHolder->maxCons *
427 sizeof(DataAdviseConnection));
428
429 TRACE("returning %p\n", newHolder);
430 return (IDataAdviseHolder*)newHolder;
431}
432
433/******************************************************************************
434 * DataAdviseHolder_Destructor
435 */
436static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy)
437{
438 DWORD index;
439 TRACE("%p\n", ptrToDestroy);
440
441 for (index = 0; index < ptrToDestroy->maxCons; index++)
442 {
443 if (ptrToDestroy->Connections[index].sink != NULL)
444 {
445 IAdviseSink_Release(ptrToDestroy->Connections[index].sink);
446 ptrToDestroy->Connections[index].sink = NULL;
447 }
448 }
449
450 HeapFree(GetProcessHeap(), 0, ptrToDestroy->Connections);
451 HeapFree(GetProcessHeap(), 0, ptrToDestroy);
452}
453
454/************************************************************************
455 * DataAdviseHolder_QueryInterface (IUnknown)
456 *
457 * See Windows documentation for more details on IUnknown methods.
458 */
459static HRESULT WINAPI DataAdviseHolder_QueryInterface(
460 IDataAdviseHolder* iface,
461 REFIID riid,
462 void** ppvObject)
463{
464 ICOM_THIS(DataAdviseHolder, iface);
465 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObject);
466 /*
467 * Perform a sanity check on the parameters.
468 */
469 if ( (This==0) || (ppvObject==0) )
470 return E_INVALIDARG;
471
472 /*
473 * Initialize the return parameter.
474 */
475 *ppvObject = 0;
476
477 /*
478 * Compare the riid with the interface IDs implemented by this object.
479 */
480 if ( (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) ||
481 (memcmp(&IID_IDataAdviseHolder, riid, sizeof(IID_IDataAdviseHolder)) == 0) )
482 {
483 *ppvObject = iface;
484 }
485
486 /*
487 * Check that we obtained an interface.
488 */
489 if ((*ppvObject)==0)
490 {
491 return E_NOINTERFACE;
492 }
493
494 /*
495 * Query Interface always increases the reference count by one when it is
496 * successful.
497 */
498 IUnknown_AddRef((IUnknown*)*ppvObject);
499
500 return S_OK;;
501}
502
503/************************************************************************
504 * DataAdviseHolder_AddRef (IUnknown)
505 *
506 * See Windows documentation for more details on IUnknown methods.
507 */
508static ULONG WINAPI DataAdviseHolder_AddRef(
509 IDataAdviseHolder* iface)
510{
511 ICOM_THIS(DataAdviseHolder, iface);
512 TRACE("(%p) (ref=%ld)\n", This, This->ref);
513 This->ref++;
514
515 return This->ref;
516}
517
518/************************************************************************
519 * DataAdviseHolder_Release (IUnknown)
520 *
521 * See Windows documentation for more details on IUnknown methods.
522 */
523static ULONG WINAPI DataAdviseHolder_Release(
524 IDataAdviseHolder* iface)
525{
526 ICOM_THIS(DataAdviseHolder, iface);
527 TRACE("(%p) (ref=%ld)\n", This, This->ref);
528
529 /*
530 * Decrease the reference count on this object.
531 */
532 This->ref--;
533
534 /*
535 * If the reference count goes down to 0, perform suicide.
536 */
537 if (This->ref==0)
538 {
539 DataAdviseHolder_Destructor(This);
540
541 return 0;
542 }
543
544 return This->ref;
545}
546
547/************************************************************************
548 * DataAdviseHolder_Advise
549 *
550 */
551static HRESULT WINAPI DataAdviseHolder_Advise(
552 IDataAdviseHolder* iface,
553 IDataObject* pDataObject,
554 FORMATETC* pFetc,
555 DWORD advf,
556 IAdviseSink* pAdvise,
557 DWORD* pdwConnection)
558{
559 DWORD index;
560
561 ICOM_THIS(DataAdviseHolder, iface);
562
563 TRACE("(%p)->(%p, %p, %08lx, %p, %p)\n", This, pDataObject, pFetc, advf,
564 pAdvise, pdwConnection);
565 /*
566 * Sanity check
567 */
568 if (pdwConnection==NULL)
569 return E_POINTER;
570
571 *pdwConnection = 0;
572
573 /*
574 * Find a free spot in the array.
575 */
576 for (index = 0; index < This->maxCons; index++)
577 {
578 if (This->Connections[index].sink == NULL)
579 break;
580 }
581
582 /*
583 * If the array is full, we need to grow it.
584 */
585 if (index == This->maxCons)
586 {
587 This->maxCons+=INITIAL_SINKS;
588 This->Connections = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
589 This->Connections,
590 This->maxCons*sizeof(DataAdviseConnection));
591 }
592 /*
593 * Store the new sink
594 */
595 This->Connections[index].sink = pAdvise;
596 memcpy(&(This->Connections[index].fmat), pFetc, sizeof(FORMATETC));
597 This->Connections[index].advf = advf;
598
599 if (This->Connections[index].sink != NULL) {
600 IAdviseSink_AddRef(This->Connections[index].sink);
601 if(advf & ADVF_PRIMEFIRST) {
602 DataAdviseHolder_SendOnDataChange(iface, pDataObject, 0, advf);
603 }
604 }
605 /*
606 * Return the index as the cookie.
607 * Since 0 is not a valid cookie, we will increment by
608 * 1 the index in the table.
609 */
610 *pdwConnection = index+1;
611
612 return S_OK;
613}
614
615/******************************************************************************
616 * DataAdviseHolder_Unadvise
617 */
618static HRESULT WINAPI DataAdviseHolder_Unadvise(
619 IDataAdviseHolder* iface,
620 DWORD dwConnection)
621{
622 ICOM_THIS(DataAdviseHolder, iface);
623
624 TRACE("(%p)->(%lu)\n", This, dwConnection);
625
626 /*
627 * So we don't return 0 as a cookie, the index was
628 * incremented by 1 in OleAdviseHolderImpl_Advise
629 * we have to compensate.
630 */
631 dwConnection--;
632
633 /*
634 * Check for invalid cookies.
635 */
636 if ( (dwConnection < 0) ||
637 (dwConnection >= This->maxCons) )
638 return OLE_E_NOCONNECTION;
639
640 if (This->Connections[dwConnection].sink == NULL)
641 return OLE_E_NOCONNECTION;
642
643 /*
644 * Release the sink and mark the spot in the list as free.
645 */
646 IAdviseSink_Release(This->Connections[dwConnection].sink);
647 memset(&(This->Connections[dwConnection]), 0, sizeof(DataAdviseConnection));
648 return S_OK;
649}
650
651static HRESULT WINAPI DataAdviseHolder_EnumAdvise(
652 IDataAdviseHolder* iface,
653 IEnumSTATDATA** ppenumAdvise)
654{
655 ICOM_THIS(DataAdviseHolder, iface);
656
657 FIXME("(%p)->(%p)\n", This, ppenumAdvise);
658 return E_NOTIMPL;
659}
660
661/******************************************************************************
662 * DataAdviseHolder_SendOnDataChange
663 */
664static HRESULT WINAPI DataAdviseHolder_SendOnDataChange(
665 IDataAdviseHolder* iface,
666 IDataObject* pDataObject,
667 DWORD dwReserved,
668 DWORD advf)
669{
670 ICOM_THIS(DataAdviseHolder, iface);
671 DWORD index;
672 STGMEDIUM stg;
673 HRESULT res;
674
675 TRACE("(%p)->(%p,%08lx,%08lx)\n", This, pDataObject, dwReserved, advf);
676
677 for(index = 0; index < This->maxCons; index++) {
678 if(This->Connections[index].sink != NULL) {
679 if(!(This->Connections[index].advf & ADVF_NODATA)) {
680 TRACE("Calling IDataObject_GetData\n");
681 res = IDataObject_GetData(pDataObject,
682 &(This->Connections[index].fmat),
683 &stg);
684 TRACE("returns %08lx\n", res);
685 }
686 TRACE("Calling IAdviseSink_OnDataChange\n");
687 IAdviseSink_OnDataChange(This->Connections[index].sink,
688 &(This->Connections[index].fmat),
689 &stg);
690 TRACE("Done IAdviseSink_OnDataChange\n");
691 if(This->Connections[index].advf & ADVF_ONLYONCE) {
692 TRACE("Removing connection\n");
693 DataAdviseHolder_Unadvise(iface, index+1);
694 }
695 }
696 }
697 return S_OK;
698}
699
700/***********************************************************************
701 * API functions
702 */
703
704/***********************************************************************
705 * CreateOleAdviseHolder [OLE32.59]
706 */
707HRESULT WINAPI CreateOleAdviseHolder(
708 LPOLEADVISEHOLDER *ppOAHolder)
709{
710 TRACE("(%p)\n", ppOAHolder);
711
712 /*
713 * Sanity check,
714 */
715 if (ppOAHolder==NULL)
716 return E_POINTER;
717
718 *ppOAHolder = OleAdviseHolderImpl_Constructor ();
719
720 if (*ppOAHolder != NULL)
721 return S_OK;
722
723 return E_OUTOFMEMORY;
724}
725
726/******************************************************************************
727 * CreateDataAdviseHolder [OLE32.53]
728 */
729HRESULT WINAPI CreateDataAdviseHolder(
730 LPDATAADVISEHOLDER* ppDAHolder)
731{
732 TRACE("(%p)\n", ppDAHolder);
733
734 /*
735 * Sanity check,
736 */
737 if (ppDAHolder==NULL)
738 return E_POINTER;
739
740 *ppDAHolder = DataAdviseHolder_Constructor();
741
742 if (*ppDAHolder != NULL)
743 return S_OK;
744
745 return E_OUTOFMEMORY;
746}
747
Note: See TracBrowser for help on using the repository browser.