Moved bulk of OLE implementation to dlls/ subdirectories.
[wine] / dlls / ole32 / oleobj.c
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 "oleidl.h"
13 #include "debugtools.h"
14
15 DEFAULT_DEBUG_CHANNEL(ole)
16
17
18 /**************************************************************************
19  *  OleAdviseHolderImpl Implementation
20  */
21 typedef struct OleAdviseHolderImpl
22 {
23   ICOM_VTABLE(IOleAdviseHolder)* lpvtbl;
24
25   DWORD ref;
26
27   DWORD         maxSinks;
28   IAdviseSink** arrayOfSinks;
29
30 } OleAdviseHolderImpl;
31
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);
43
44
45 /**************************************************************************
46  *  OleAdviseHolderImpl_VTable
47  */
48 static struct ICOM_VTABLE(IOleAdviseHolder) oahvt =
49 {
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
59 };
60
61 /**************************************************************************
62  *  OleAdviseHolderImpl_Constructor
63  */
64
65 static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor()
66 {
67   OleAdviseHolderImpl* lpoah;
68   DWORD                index;
69
70   lpoah= (OleAdviseHolderImpl*)HeapAlloc(GetProcessHeap(),
71                                          0,
72                                          sizeof(OleAdviseHolderImpl));
73   
74   lpoah->lpvtbl = &oahvt;
75   lpoah->ref = 1;
76   lpoah->maxSinks = 10;
77   lpoah->arrayOfSinks = HeapAlloc(GetProcessHeap(),
78                                   0,
79                                   lpoah->maxSinks * sizeof(IAdviseSink*));
80
81   for (index = 0; index < lpoah->maxSinks; index++)
82     lpoah->arrayOfSinks[index]=0;
83
84   return (LPOLEADVISEHOLDER)lpoah;
85 }
86
87 /**************************************************************************
88  *  OleAdviseHolderImpl_Destructor
89  */
90 static void OleAdviseHolderImpl_Destructor(
91   OleAdviseHolderImpl* ptrToDestroy)
92 {
93   DWORD index;
94
95   for (index = 0; index < ptrToDestroy->maxSinks; index++)
96   {
97     if (ptrToDestroy->arrayOfSinks[index]!=0)
98     {
99       IAdviseSink_Release(ptrToDestroy->arrayOfSinks[index]);
100       ptrToDestroy->arrayOfSinks[index] = NULL;
101     }
102   }
103   
104   HeapFree(GetProcessHeap(),
105            0,
106            ptrToDestroy->arrayOfSinks);
107   
108
109   HeapFree(GetProcessHeap(),
110            0,
111            ptrToDestroy);
112 }
113
114 /**************************************************************************
115  *  OleAdviseHolderImpl_QueryInterface
116  */
117 static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(
118   LPOLEADVISEHOLDER iface,
119   REFIID            riid, 
120   LPVOID*           ppvObj)
121 {
122   ICOM_THIS(OleAdviseHolderImpl, iface); 
123
124   /*
125    * Sanity check
126    */
127   if (ppvObj==NULL)
128     return E_POINTER;
129
130   *ppvObj = NULL;
131
132   if (IsEqualIID(riid, &IID_IUnknown)) 
133   {
134     /* IUnknown */
135     *ppvObj = This; 
136   }
137   else if(IsEqualIID(riid, &IID_IOleAdviseHolder)) 
138   {
139     /* IOleAdviseHolder */
140     *ppvObj = (IOleAdviseHolder*) This;
141   }
142
143   if(*ppvObj == NULL)
144     return E_NOINTERFACE;
145   
146   /*
147    * A successful QI always increments the reference count.
148    */
149   IUnknown_AddRef((IUnknown*)*ppvObj);
150
151   return S_OK;
152 }
153
154 /******************************************************************************
155  * OleAdviseHolderImpl_AddRef
156  */
157 static ULONG WINAPI OleAdviseHolderImpl_AddRef(
158   LPOLEADVISEHOLDER iface)
159 {
160   ICOM_THIS(OleAdviseHolderImpl, iface); 
161   
162   return ++(This->ref);
163 }
164
165 /******************************************************************************
166  * OleAdviseHolderImpl_Release
167  */
168 static ULONG WINAPI OleAdviseHolderImpl_Release(
169   LPOLEADVISEHOLDER iface)
170 {
171   ICOM_THIS(OleAdviseHolderImpl, iface); 
172
173   This->ref--;
174
175   if (This->ref == 0)
176   {
177     OleAdviseHolderImpl_Destructor(This);
178
179     return 0;
180   }
181
182   return This->ref;
183 }
184
185 /******************************************************************************
186  * OleAdviseHolderImpl_Advise
187  */
188 static HRESULT WINAPI OleAdviseHolderImpl_Advise(
189   LPOLEADVISEHOLDER iface,
190   IAdviseSink*      pAdvise,
191   DWORD*            pdwConnection)
192 {
193   DWORD index;
194   
195   ICOM_THIS(OleAdviseHolderImpl, iface); 
196
197   TRACE("(%p, %p, %p)\n", This, pAdvise, pdwConnection);
198
199   /*
200    * Sanity check
201    */
202   if (pdwConnection==NULL)
203     return E_POINTER;
204   
205   *pdwConnection = 0;
206
207   /*
208    * Find a free spot in the array.
209    */
210   for (index = 0; index < This->maxSinks; index++)
211   {
212     if (This->arrayOfSinks[index]==NULL)
213       break;
214   }
215
216   /*
217    * If the array is full, we need to grow it.
218    */
219   if (index == This->maxSinks)
220   {
221     DWORD i;
222
223     This->maxSinks+=10;
224
225     This->arrayOfSinks = HeapReAlloc(GetProcessHeap(), 
226                                      0,
227                                      This->arrayOfSinks,
228                                      This->maxSinks*sizeof(IAdviseSink*));
229
230     for (i=index;i < This->maxSinks; i++)
231       This->arrayOfSinks[i]=0;      
232   }
233
234   /*
235    * Store the new sink
236    */
237   This->arrayOfSinks[index] = pAdvise;
238
239   if (This->arrayOfSinks[index]!=NULL)
240     IAdviseSink_AddRef(This->arrayOfSinks[index]);
241
242   /*
243    * Return the index as the cookie.
244    * Since 0 is not a valid cookie, we will increment by
245    * 1 the index in the table.
246    */
247   *pdwConnection = index+1;
248
249   return S_OK;
250 }
251
252 /******************************************************************************
253  * OleAdviseHolderImpl_Unadvise
254  */
255 static HRESULT WINAPI OleAdviseHolderImpl_Unadvise(
256   LPOLEADVISEHOLDER iface, 
257   DWORD             dwConnection)
258 {
259   ICOM_THIS(OleAdviseHolderImpl, iface); 
260
261   TRACE("(%p, %lu)\n", This, dwConnection);
262
263   /*
264    * So we don't return 0 as a cookie, the index was 
265    * incremented by 1 in OleAdviseHolderImpl_Advise
266    * we have to compensate.
267    */
268   dwConnection--;
269   
270   /*
271    * Check for invalid cookies.
272    */
273   if ( (dwConnection < 0) || 
274        (dwConnection >= This->maxSinks) )
275     return OLE_E_NOCONNECTION;
276
277   if (This->arrayOfSinks[dwConnection] == NULL)
278     return OLE_E_NOCONNECTION;
279
280   /*
281    * Release the sink and mark the spot in the list as free.
282    */
283   IAdviseSink_Release(This->arrayOfSinks[dwConnection]);
284   This->arrayOfSinks[dwConnection] = NULL;
285
286   return S_OK;
287 }
288
289 /******************************************************************************
290  * OleAdviseHolderImpl_EnumAdvise
291  */
292 static HRESULT WINAPI
293 OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER iface, IEnumSTATDATA **ppenumAdvise)
294 {
295                 ICOM_THIS(OleAdviseHolderImpl, iface); 
296     FIXME("(%p)->(%p)\n", This, ppenumAdvise);
297
298     *ppenumAdvise = NULL;
299
300     return S_OK;
301 }
302
303 /******************************************************************************
304  * OleAdviseHolderImpl_SendOnRename
305  */
306 static HRESULT WINAPI
307 OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk)
308 {
309                 ICOM_THIS(OleAdviseHolderImpl, iface); 
310     FIXME("(%p)->(%p)\n", This, pmk);
311
312
313     return S_OK;
314 }
315
316 /******************************************************************************
317  * OleAdviseHolderImpl_SendOnSave
318  */
319 static HRESULT WINAPI
320 OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface)
321 {
322                 ICOM_THIS(OleAdviseHolderImpl, iface); 
323     FIXME("(%p)\n", This);
324
325
326     return S_OK;
327 }
328
329 /******************************************************************************
330  * OleAdviseHolderImpl_SendOnClose
331  */
332 static HRESULT WINAPI
333 OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface)
334 {
335   ICOM_THIS(OleAdviseHolderImpl, iface); 
336     FIXME("(%p)\n", This);
337
338
339     return S_OK;
340 }
341
342 /**************************************************************************
343  *  DataAdviseHolder Implementation
344  */
345 typedef struct DataAdviseHolder
346 {
347   ICOM_VTABLE(IDataAdviseHolder)* lpvtbl;
348
349   DWORD ref;
350 } DataAdviseHolder;
351
352 /**************************************************************************
353  *  DataAdviseHolder method prototypes
354  */
355 static IDataAdviseHolder* DataAdviseHolder_Constructor();
356 static void               DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy);
357 static HRESULT WINAPI     DataAdviseHolder_QueryInterface(
358                             IDataAdviseHolder*      iface,
359                             REFIID                  riid,
360                             void**                  ppvObject);
361 static ULONG WINAPI       DataAdviseHolder_AddRef( 
362                             IDataAdviseHolder*      iface);
363 static ULONG WINAPI       DataAdviseHolder_Release( 
364                             IDataAdviseHolder*      iface);
365 static HRESULT WINAPI     DataAdviseHolder_Advise( 
366                             IDataAdviseHolder*      iface,
367                             IDataObject*            pDataObject, 
368                             FORMATETC*              pFetc, 
369                             DWORD                   advf, 
370                             IAdviseSink*            pAdvise, 
371                             DWORD*                  pdwConnection);
372 static HRESULT WINAPI     DataAdviseHolder_Unadvise( 
373                             IDataAdviseHolder*      iface,
374                             DWORD                   dwConnection);
375 static HRESULT WINAPI     DataAdviseHolder_EnumAdvise( 
376                             IDataAdviseHolder*      iface,       
377                             IEnumSTATDATA**         ppenumAdvise);
378 static HRESULT WINAPI     DataAdviseHolder_SendOnDataChange( 
379                             IDataAdviseHolder*      iface, 
380                             IDataObject*            pDataObject, 
381                             DWORD                   dwReserved, 
382                             DWORD                   advf);
383
384 /**************************************************************************
385  *  DataAdviseHolderImpl_VTable
386  */
387 static struct ICOM_VTABLE(IDataAdviseHolder) DataAdviseHolderImpl_VTable =
388 {
389   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
390   DataAdviseHolder_QueryInterface,
391   DataAdviseHolder_AddRef,
392   DataAdviseHolder_Release,
393   DataAdviseHolder_Advise,
394   DataAdviseHolder_Unadvise,
395   DataAdviseHolder_EnumAdvise,
396   DataAdviseHolder_SendOnDataChange
397 };
398
399 /******************************************************************************
400  * DataAdviseHolder_Constructor
401  */
402 static IDataAdviseHolder* DataAdviseHolder_Constructor()
403 {
404   DataAdviseHolder* newHolder;
405
406   newHolder = (DataAdviseHolder*)HeapAlloc(GetProcessHeap(),
407                                            0,
408                                            sizeof(DataAdviseHolder));
409   
410   newHolder->lpvtbl = &DataAdviseHolderImpl_VTable;
411   newHolder->ref = 1;
412
413   return (IDataAdviseHolder*)newHolder;
414 }
415
416 /******************************************************************************
417  * DataAdviseHolder_Destructor
418  */
419 static void DataAdviseHolder_Destructor(
420   DataAdviseHolder* ptrToDestroy)
421 {
422   HeapFree(GetProcessHeap(),
423            0,
424            ptrToDestroy);
425 }
426
427 /************************************************************************
428  * DataAdviseHolder_QueryInterface (IUnknown)
429  *
430  * See Windows documentation for more details on IUnknown methods.
431  */
432 static HRESULT WINAPI DataAdviseHolder_QueryInterface(
433   IDataAdviseHolder*      iface,
434   REFIID                  riid,
435   void**                  ppvObject)
436 {
437   ICOM_THIS(DataAdviseHolder, iface); 
438
439   /*
440    * Perform a sanity check on the parameters.
441    */
442   if ( (This==0) || (ppvObject==0) )
443     return E_INVALIDARG;
444   
445   /*
446    * Initialize the return parameter.
447    */
448   *ppvObject = 0;
449
450   /*
451    * Compare the riid with the interface IDs implemented by this object.
452    */
453   if ( (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) ||
454        (memcmp(&IID_IDataAdviseHolder, riid, sizeof(IID_IDataAdviseHolder)) == 0)  )
455   {
456     *ppvObject = iface;
457   }
458   
459   /*
460    * Check that we obtained an interface.
461    */
462   if ((*ppvObject)==0)
463   {
464     return E_NOINTERFACE;
465   }
466   
467   /*
468    * Query Interface always increases the reference count by one when it is
469    * successful. 
470    */
471   IUnknown_AddRef((IUnknown*)*ppvObject);
472
473   return S_OK;;  
474 }
475
476 /************************************************************************
477  * DataAdviseHolder_AddRef (IUnknown)
478  *
479  * See Windows documentation for more details on IUnknown methods.
480  */
481 static ULONG WINAPI       DataAdviseHolder_AddRef(                             
482   IDataAdviseHolder*      iface)
483 {
484   ICOM_THIS(DataAdviseHolder, iface); 
485
486   This->ref++;
487
488   return This->ref;
489 }
490
491 /************************************************************************
492  * DataAdviseHolder_Release (IUnknown)
493  *
494  * See Windows documentation for more details on IUnknown methods.
495  */
496 static ULONG WINAPI DataAdviseHolder_Release( 
497   IDataAdviseHolder*      iface)
498 {
499   ICOM_THIS(DataAdviseHolder, iface); 
500
501   /*
502    * Decrease the reference count on this object.
503    */
504   This->ref--;
505
506   /*
507    * If the reference count goes down to 0, perform suicide.
508    */
509   if (This->ref==0)
510   {
511     DataAdviseHolder_Destructor(This);
512
513     return 0;
514   }
515   
516   return This->ref;
517 }
518
519 static HRESULT WINAPI DataAdviseHolder_Advise(
520   IDataAdviseHolder*      iface,
521   IDataObject*            pDataObject, 
522   FORMATETC*              pFetc, 
523   DWORD                   advf, 
524   IAdviseSink*            pAdvise, 
525   DWORD*                  pdwConnection)
526 {
527   FIXME("(): stub\n");
528   return E_NOTIMPL;
529 }
530
531 static HRESULT WINAPI     DataAdviseHolder_Unadvise( 
532   IDataAdviseHolder*      iface,
533   DWORD                   dwConnection)
534 {
535   FIXME("(): stub\n");
536   return E_NOTIMPL;
537 }
538
539 static HRESULT WINAPI     DataAdviseHolder_EnumAdvise( 
540   IDataAdviseHolder*      iface,       
541   IEnumSTATDATA**         ppenumAdvise)
542 {
543   FIXME("(): stub\n");
544   return E_NOTIMPL;
545 }
546
547 static HRESULT WINAPI     DataAdviseHolder_SendOnDataChange( 
548   IDataAdviseHolder*      iface, 
549   IDataObject*            pDataObject, 
550   DWORD                   dwReserved, 
551   DWORD                   advf)
552 {
553   FIXME("(): stub\n");
554   return E_NOTIMPL;
555 }
556
557 /***********************************************************************
558  * API functions
559  */
560
561 /***********************************************************************
562  * CreateOleAdviseHolder [OLE32.59]
563  */
564 HRESULT WINAPI CreateOleAdviseHolder(
565   LPOLEADVISEHOLDER *ppOAHolder)
566 {
567   TRACE("(%p)\n", ppOAHolder);
568
569   /*
570    * Sanity check,
571    */
572   if (ppOAHolder==NULL)
573     return E_POINTER;
574
575   *ppOAHolder = OleAdviseHolderImpl_Constructor ();
576
577   if (*ppOAHolder != NULL)
578     return S_OK;
579
580   return E_OUTOFMEMORY;
581 }
582
583 /******************************************************************************
584  *              CreateDataAdviseHolder        [OLE32.53]
585  */
586 HRESULT WINAPI CreateDataAdviseHolder(
587   LPDATAADVISEHOLDER* ppDAHolder)
588 {
589   TRACE("(%p)\n", ppDAHolder);
590
591   /*
592    * Sanity check,
593    */
594   if (ppDAHolder==NULL)
595     return E_POINTER;
596
597   *ppDAHolder = DataAdviseHolder_Constructor();
598
599   if (*ppDAHolder != NULL)
600     return S_OK;
601
602   return E_OUTOFMEMORY;
603 }
604