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

Last change on this file since 7502 was 7502, checked in by phaller, 24 years ago

Fixed out-of-scope FIXME,TRACE,WARN macros

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