Fixed wrong NE module registration so that resources work.
[wine] / ole / 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 "debug.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(ole, "(%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(ole, "(%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 (ole, "(%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 (ole, "(%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 (ole, "(%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 (ole, "(%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   DataAdviseHolder_QueryInterface,
390   DataAdviseHolder_AddRef,
391   DataAdviseHolder_Release,
392   DataAdviseHolder_Advise,
393   DataAdviseHolder_Unadvise,
394   DataAdviseHolder_EnumAdvise,
395   DataAdviseHolder_SendOnDataChange
396 };
397
398 /******************************************************************************
399  * DataAdviseHolder_Constructor
400  */
401 static IDataAdviseHolder* DataAdviseHolder_Constructor()
402 {
403   DataAdviseHolder* newHolder;
404
405   newHolder = (DataAdviseHolder*)HeapAlloc(GetProcessHeap(),
406                                            0,
407                                            sizeof(DataAdviseHolder));
408   
409   newHolder->lpvtbl = &DataAdviseHolderImpl_VTable;
410   newHolder->ref = 1;
411
412   return (IDataAdviseHolder*)newHolder;
413 }
414
415 /******************************************************************************
416  * DataAdviseHolder_Destructor
417  */
418 static void DataAdviseHolder_Destructor(
419   DataAdviseHolder* ptrToDestroy)
420 {
421   HeapFree(GetProcessHeap(),
422            0,
423            ptrToDestroy);
424 }
425
426 /************************************************************************
427  * DataAdviseHolder_QueryInterface (IUnknown)
428  *
429  * See Windows documentation for more details on IUnknown methods.
430  */
431 static HRESULT WINAPI DataAdviseHolder_QueryInterface(
432   IDataAdviseHolder*      iface,
433   REFIID                  riid,
434   void**                  ppvObject)
435 {
436   ICOM_THIS(DataAdviseHolder, iface); 
437
438   /*
439    * Perform a sanity check on the parameters.
440    */
441   if ( (This==0) || (ppvObject==0) )
442     return E_INVALIDARG;
443   
444   /*
445    * Initialize the return parameter.
446    */
447   *ppvObject = 0;
448
449   /*
450    * Compare the riid with the interface IDs implemented by this object.
451    */
452   if ( (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) ||
453        (memcmp(&IID_IDataAdviseHolder, riid, sizeof(IID_IDataAdviseHolder)) == 0)  )
454   {
455     *ppvObject = iface;
456   }
457   
458   /*
459    * Check that we obtained an interface.
460    */
461   if ((*ppvObject)==0)
462   {
463     return E_NOINTERFACE;
464   }
465   
466   /*
467    * Query Interface always increases the reference count by one when it is
468    * successful. 
469    */
470   IUnknown_AddRef((IUnknown*)*ppvObject);
471
472   return S_OK;;  
473 }
474
475 /************************************************************************
476  * DataAdviseHolder_AddRef (IUnknown)
477  *
478  * See Windows documentation for more details on IUnknown methods.
479  */
480 static ULONG WINAPI       DataAdviseHolder_AddRef(                             
481   IDataAdviseHolder*      iface)
482 {
483   ICOM_THIS(DataAdviseHolder, iface); 
484
485   This->ref++;
486
487   return This->ref;
488 }
489
490 /************************************************************************
491  * DataAdviseHolder_Release (IUnknown)
492  *
493  * See Windows documentation for more details on IUnknown methods.
494  */
495 static ULONG WINAPI DataAdviseHolder_Release( 
496   IDataAdviseHolder*      iface)
497 {
498   ICOM_THIS(DataAdviseHolder, iface); 
499
500   /*
501    * Decrease the reference count on this object.
502    */
503   This->ref--;
504
505   /*
506    * If the reference count goes down to 0, perform suicide.
507    */
508   if (This->ref==0)
509   {
510     DataAdviseHolder_Destructor(This);
511
512     return 0;
513   }
514   
515   return This->ref;
516 }
517
518 static HRESULT WINAPI DataAdviseHolder_Advise(
519   IDataAdviseHolder*      iface,
520   IDataObject*            pDataObject, 
521   FORMATETC*              pFetc, 
522   DWORD                   advf, 
523   IAdviseSink*            pAdvise, 
524   DWORD*                  pdwConnection)
525 {
526   FIXME(ole, "(): stub\n");
527   return E_NOTIMPL;
528 }
529
530 static HRESULT WINAPI     DataAdviseHolder_Unadvise( 
531   IDataAdviseHolder*      iface,
532   DWORD                   dwConnection)
533 {
534   FIXME(ole, "(): stub\n");
535   return E_NOTIMPL;
536 }
537
538 static HRESULT WINAPI     DataAdviseHolder_EnumAdvise( 
539   IDataAdviseHolder*      iface,       
540   IEnumSTATDATA**         ppenumAdvise)
541 {
542   FIXME(ole, "(): stub\n");
543   return E_NOTIMPL;
544 }
545
546 static HRESULT WINAPI     DataAdviseHolder_SendOnDataChange( 
547   IDataAdviseHolder*      iface, 
548   IDataObject*            pDataObject, 
549   DWORD                   dwReserved, 
550   DWORD                   advf)
551 {
552   FIXME(ole, "(): stub\n");
553   return E_NOTIMPL;
554 }
555
556 /***********************************************************************
557  * API functions
558  */
559
560 /***********************************************************************
561  * CreateOleAdviseHolder [OLE32.59]
562  */
563 HRESULT WINAPI CreateOleAdviseHolder(
564   LPOLEADVISEHOLDER *ppOAHolder)
565 {
566   TRACE(ole, "(%p)\n", ppOAHolder);
567
568   /*
569    * Sanity check,
570    */
571   if (ppOAHolder==NULL)
572     return E_POINTER;
573
574   *ppOAHolder = OleAdviseHolderImpl_Constructor ();
575
576   if (*ppOAHolder != NULL)
577     return S_OK;
578
579   return E_OUTOFMEMORY;
580 }
581
582 /******************************************************************************
583  *              CreateDataAdviseHolder        [OLE32.53]
584  */
585 HRESULT WINAPI CreateDataAdviseHolder(
586   LPDATAADVISEHOLDER* ppDAHolder)
587 {
588   TRACE(ole,"(%p)\n", ppDAHolder);
589
590   /*
591    * Sanity check,
592    */
593   if (ppDAHolder==NULL)
594     return E_POINTER;
595
596   *ppDAHolder = DataAdviseHolder_Constructor();
597
598   if (*ppDAHolder != NULL)
599     return S_OK;
600
601   return E_OUTOFMEMORY;
602 }
603