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

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

restored old version + wine update

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