kernel32: Fix the case where memory is freed twice in GlobalFree.
[wine] / dlls / mshtml / htmlbody.c
1 /*
2  * Copyright 2006 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "config.h"
20
21 #include <stdarg.h>
22 #include <stdio.h>
23
24 #define COBJMACROS
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "winnls.h"
30 #include "ole2.h"
31
32 #include "wine/debug.h"
33
34 #include "mshtml_private.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
37
38 typedef struct {
39     HTMLTextContainer textcont;
40
41     const IHTMLBodyElementVtbl *lpHTMLBodyElementVtbl;
42
43     HTMLTextContainer text_container;
44
45     ConnectionPointContainer cp_container;
46     ConnectionPoint cp_propnotif;
47     ConnectionPoint cp_txtcontevents;
48
49     nsIDOMHTMLBodyElement *nsbody;
50 } HTMLBodyElement;
51
52 #define HTMLBODY(x)  ((IHTMLBodyElement*)  &(x)->lpHTMLBodyElementVtbl)
53
54 #define HTMLBODY_THIS(iface) DEFINE_THIS(HTMLBodyElement, HTMLBodyElement, iface)
55
56 static HRESULT WINAPI HTMLBodyElement_QueryInterface(IHTMLBodyElement *iface,
57                                                      REFIID riid, void **ppv)
58 {
59     HTMLBodyElement *This = HTMLBODY_THIS(iface);
60     HRESULT hres;
61
62     *ppv = NULL;
63
64     if(IsEqualGUID(&IID_IUnknown, riid)) {
65         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
66         *ppv = HTMLBODY(This);
67     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
68         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
69         *ppv = HTMLBODY(This);
70     }else if(IsEqualGUID(&IID_IHTMLBodyElement, riid)) {
71         TRACE("(%p)->(IID_IHTMLBodyElement %p)\n", This, ppv);
72         *ppv = HTMLBODY(This);
73     }else if(IsEqualGUID(&IID_IHTMLTextContainer, riid)) {
74         TRACE("(%p)->(IID_IHTMLTextContainer %p)\n", This, ppv);
75         *ppv = HTMLTEXTCONT(&This->text_container);
76     }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
77         TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
78         *ppv = CONPTCONT(&This->cp_container);
79     }
80
81     if(*ppv) {
82         IUnknown_AddRef((IUnknown*)*ppv);
83         return S_OK;
84     }
85
86     hres = HTMLElement_QI(&This->textcont.element, riid, ppv);
87     if(FAILED(hres))
88         WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
89
90     return hres;
91 }
92
93 static ULONG WINAPI HTMLBodyElement_AddRef(IHTMLBodyElement *iface)
94 {
95     HTMLBodyElement *This = HTMLBODY_THIS(iface);
96
97     TRACE("(%p)\n", This);
98
99     return IHTMLDocument2_AddRef(HTMLDOC(This->textcont.element.node.doc));
100 }
101
102 static ULONG WINAPI HTMLBodyElement_Release(IHTMLBodyElement *iface)
103 {
104     HTMLBodyElement *This = HTMLBODY_THIS(iface);
105
106     TRACE("(%p)\n", This);
107
108     return IHTMLDocument2_Release(HTMLDOC(This->textcont.element.node.doc));
109 }
110
111 static HRESULT WINAPI HTMLBodyElement_GetTypeInfoCount(IHTMLBodyElement *iface, UINT *pctinfo)
112 {
113     HTMLBodyElement *This = HTMLBODY_THIS(iface);
114     FIXME("(%p)->(%p)\n", This, pctinfo);
115     return E_NOTIMPL;
116 }
117
118 static HRESULT WINAPI HTMLBodyElement_GetTypeInfo(IHTMLBodyElement *iface, UINT iTInfo,
119                                               LCID lcid, ITypeInfo **ppTInfo)
120 {
121     HTMLBodyElement *This = HTMLBODY_THIS(iface);
122     FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
123     return E_NOTIMPL;
124 }
125
126 static HRESULT WINAPI HTMLBodyElement_GetIDsOfNames(IHTMLBodyElement *iface, REFIID riid,
127                                                 LPOLESTR *rgszNames, UINT cNames,
128                                                 LCID lcid, DISPID *rgDispId)
129 {
130     HTMLBodyElement *This = HTMLBODY_THIS(iface);
131     FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
132                                         lcid, rgDispId);
133     return E_NOTIMPL;
134 }
135
136 static HRESULT WINAPI HTMLBodyElement_Invoke(IHTMLBodyElement *iface, DISPID dispIdMember,
137                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
138                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
139 {
140     HTMLBodyElement *This = HTMLBODY_THIS(iface);
141     FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
142             lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
143     return E_NOTIMPL;
144 }
145
146 static HRESULT WINAPI HTMLBodyElement_put_background(IHTMLBodyElement *iface, BSTR v)
147 {
148     HTMLBodyElement *This = HTMLBODY_THIS(iface);
149     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
150     return E_NOTIMPL;
151 }
152
153 static HRESULT WINAPI HTMLBodyElement_get_background(IHTMLBodyElement *iface, BSTR *p)
154 {
155     HTMLBodyElement *This = HTMLBODY_THIS(iface);
156     nsAString background_str;
157     nsresult nsres;
158
159     TRACE("(%p)->(%p)\n", This, p);
160
161     nsAString_Init(&background_str, NULL);
162
163     nsres = nsIDOMHTMLBodyElement_GetBackground(This->nsbody, &background_str);
164     if(NS_SUCCEEDED(nsres)) {
165         const PRUnichar *background;
166         nsAString_GetData(&background_str, &background, NULL);
167         *p = SysAllocString(background);
168     }else {
169         ERR("GetBackground failed: %08x\n", nsres);
170         *p = NULL;
171     }
172
173     nsAString_Finish(&background_str);
174
175     TRACE("*p = %s\n", debugstr_w(*p));
176     return S_OK;
177 }
178
179 static HRESULT WINAPI HTMLBodyElement_put_bgProperties(IHTMLBodyElement *iface, BSTR v)
180 {
181     HTMLBodyElement *This = HTMLBODY_THIS(iface);
182     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
183     return E_NOTIMPL;
184 }
185
186 static HRESULT WINAPI HTMLBodyElement_get_bgProperties(IHTMLBodyElement *iface, BSTR *p)
187 {
188     HTMLBodyElement *This = HTMLBODY_THIS(iface);
189     FIXME("(%p)->(%p)\n", This, p);
190     return E_NOTIMPL;
191 }
192
193 static HRESULT WINAPI HTMLBodyElement_put_leftMargin(IHTMLBodyElement *iface, VARIANT v)
194 {
195     HTMLBodyElement *This = HTMLBODY_THIS(iface);
196     FIXME("(%p)->()\n", This);
197     return E_NOTIMPL;
198 }
199
200 static HRESULT WINAPI HTMLBodyElement_get_leftMargin(IHTMLBodyElement *iface, VARIANT *p)
201 {
202     HTMLBodyElement *This = HTMLBODY_THIS(iface);
203     FIXME("(%p)->(%p)\n", This, p);
204     return E_NOTIMPL;
205 }
206
207 static HRESULT WINAPI HTMLBodyElement_put_topMargin(IHTMLBodyElement *iface, VARIANT v)
208 {
209     HTMLBodyElement *This = HTMLBODY_THIS(iface);
210     FIXME("(%p)->()\n", This);
211     return E_NOTIMPL;
212 }
213
214 static HRESULT WINAPI HTMLBodyElement_get_topMargin(IHTMLBodyElement *iface, VARIANT *p)
215 {
216     HTMLBodyElement *This = HTMLBODY_THIS(iface);
217     FIXME("(%p)->(%p)\n", This, p);
218     return E_NOTIMPL;
219 }
220
221 static HRESULT WINAPI HTMLBodyElement_put_rightMargin(IHTMLBodyElement *iface, VARIANT v)
222 {
223     HTMLBodyElement *This = HTMLBODY_THIS(iface);
224     FIXME("(%p)->()\n", This);
225     return E_NOTIMPL;
226 }
227
228 static HRESULT WINAPI HTMLBodyElement_get_rightMargin(IHTMLBodyElement *iface, VARIANT *p)
229 {
230     HTMLBodyElement *This = HTMLBODY_THIS(iface);
231     FIXME("(%p)->(%p)\n", This, p);
232     return E_NOTIMPL;
233 }
234
235 static HRESULT WINAPI HTMLBodyElement_put_bottomMargin(IHTMLBodyElement *iface, VARIANT v)
236 {
237     HTMLBodyElement *This = HTMLBODY_THIS(iface);
238     FIXME("(%p)->()\n", This);
239     return E_NOTIMPL;
240 }
241
242 static HRESULT WINAPI HTMLBodyElement_get_bottomMargin(IHTMLBodyElement *iface, VARIANT *p)
243 {
244     HTMLBodyElement *This = HTMLBODY_THIS(iface);
245     FIXME("(%p)->(%p)\n", This, p);
246     return E_NOTIMPL;
247 }
248
249 static HRESULT WINAPI HTMLBodyElement_put_noWrap(IHTMLBodyElement *iface, VARIANT_BOOL v)
250 {
251     HTMLBodyElement *This = HTMLBODY_THIS(iface);
252     FIXME("(%p)->(%x)\n", This, v);
253     return E_NOTIMPL;
254 }
255
256 static HRESULT WINAPI HTMLBodyElement_get_noWrap(IHTMLBodyElement *iface, VARIANT_BOOL *p)
257 {
258     HTMLBodyElement *This = HTMLBODY_THIS(iface);
259     FIXME("(%p)->(%p)\n", This, p);
260     return E_NOTIMPL;
261 }
262
263 static HRESULT WINAPI HTMLBodyElement_put_bgColor(IHTMLBodyElement *iface, VARIANT v)
264 {
265     HTMLBodyElement *This = HTMLBODY_THIS(iface);
266     FIXME("(%p)->()\n", This);
267     return E_NOTIMPL;
268 }
269
270 static HRESULT WINAPI HTMLBodyElement_get_bgColor(IHTMLBodyElement *iface, VARIANT *p)
271 {
272     HTMLBodyElement *This = HTMLBODY_THIS(iface);
273     FIXME("(%p)->(%p)\n", This, p);
274     return E_NOTIMPL;
275 }
276
277 static HRESULT WINAPI HTMLBodyElement_put_text(IHTMLBodyElement *iface, VARIANT v)
278 {
279     HTMLBodyElement *This = HTMLBODY_THIS(iface);
280     FIXME("(%p)->()\n", This);
281     return E_NOTIMPL;
282 }
283
284 static HRESULT WINAPI HTMLBodyElement_get_text(IHTMLBodyElement *iface, VARIANT *p)
285 {
286     HTMLBodyElement *This = HTMLBODY_THIS(iface);
287     FIXME("(%p)->(%p)\n", This, p);
288     return E_NOTIMPL;
289 }
290
291 static HRESULT WINAPI HTMLBodyElement_put_link(IHTMLBodyElement *iface, VARIANT v)
292 {
293     HTMLBodyElement *This = HTMLBODY_THIS(iface);
294     FIXME("(%p)->()\n", This);
295     return E_NOTIMPL;
296 }
297
298 static HRESULT WINAPI HTMLBodyElement_get_link(IHTMLBodyElement *iface, VARIANT *p)
299 {
300     HTMLBodyElement *This = HTMLBODY_THIS(iface);
301     FIXME("(%p)->(%p)\n", This, p);
302     return E_NOTIMPL;
303 }
304
305 static HRESULT WINAPI HTMLBodyElement_put_vLink(IHTMLBodyElement *iface, VARIANT v)
306 {
307     HTMLBodyElement *This = HTMLBODY_THIS(iface);
308     FIXME("(%p)->()\n", This);
309     return E_NOTIMPL;
310 }
311
312 static HRESULT WINAPI HTMLBodyElement_get_vLink(IHTMLBodyElement *iface, VARIANT *p)
313 {
314     HTMLBodyElement *This = HTMLBODY_THIS(iface);
315     FIXME("(%p)->(%p)\n", This, p);
316     return E_NOTIMPL;
317 }
318
319 static HRESULT WINAPI HTMLBodyElement_put_aLink(IHTMLBodyElement *iface, VARIANT v)
320 {
321     HTMLBodyElement *This = HTMLBODY_THIS(iface);
322     FIXME("(%p)->()\n", This);
323     return E_NOTIMPL;
324 }
325
326 static HRESULT WINAPI HTMLBodyElement_get_aLink(IHTMLBodyElement *iface, VARIANT *p)
327 {
328     HTMLBodyElement *This = HTMLBODY_THIS(iface);
329     FIXME("(%p)->(%p)\n", This, p);
330     return E_NOTIMPL;
331 }
332
333 static HRESULT WINAPI HTMLBodyElement_put_onload(IHTMLBodyElement *iface, VARIANT v)
334 {
335     HTMLBodyElement *This = HTMLBODY_THIS(iface);
336     FIXME("(%p)->()\n", This);
337     return E_NOTIMPL;
338 }
339
340 static HRESULT WINAPI HTMLBodyElement_get_onload(IHTMLBodyElement *iface, VARIANT *p)
341 {
342     HTMLBodyElement *This = HTMLBODY_THIS(iface);
343     FIXME("(%p)->(%p)\n", This, p);
344     return E_NOTIMPL;
345 }
346
347 static HRESULT WINAPI HTMLBodyElement_put_onunload(IHTMLBodyElement *iface, VARIANT v)
348 {
349     HTMLBodyElement *This = HTMLBODY_THIS(iface);
350     FIXME("(%p)->()\n", This);
351     return E_NOTIMPL;
352 }
353
354 static HRESULT WINAPI HTMLBodyElement_get_onunload(IHTMLBodyElement *iface, VARIANT *p)
355 {
356     HTMLBodyElement *This = HTMLBODY_THIS(iface);
357     FIXME("(%p)->(%p)\n", This, p);
358     return E_NOTIMPL;
359 }
360
361 static HRESULT WINAPI HTMLBodyElement_put_scroll(IHTMLBodyElement *iface, BSTR v)
362 {
363     HTMLBodyElement *This = HTMLBODY_THIS(iface);
364     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
365     return E_NOTIMPL;
366 }
367
368 static HRESULT WINAPI HTMLBodyElement_get_scroll(IHTMLBodyElement *iface, BSTR *p)
369 {
370     HTMLBodyElement *This = HTMLBODY_THIS(iface);
371     FIXME("(%p)->(%p)\n", This, p);
372     return E_NOTIMPL;
373 }
374
375 static HRESULT WINAPI HTMLBodyElement_put_onselect(IHTMLBodyElement *iface, VARIANT v)
376 {
377     HTMLBodyElement *This = HTMLBODY_THIS(iface);
378     FIXME("(%p)->()\n", This);
379     return E_NOTIMPL;
380 }
381
382 static HRESULT WINAPI HTMLBodyElement_get_onselect(IHTMLBodyElement *iface, VARIANT *p)
383 {
384     HTMLBodyElement *This = HTMLBODY_THIS(iface);
385     FIXME("(%p)->(%p)\n", This, p);
386     return E_NOTIMPL;
387 }
388
389 static HRESULT WINAPI HTMLBodyElement_put_onbeforeunload(IHTMLBodyElement *iface, VARIANT v)
390 {
391     HTMLBodyElement *This = HTMLBODY_THIS(iface);
392     FIXME("(%p)->()\n", This);
393     return E_NOTIMPL;
394 }
395
396 static HRESULT WINAPI HTMLBodyElement_get_onbeforeunload(IHTMLBodyElement *iface, VARIANT *p)
397 {
398     HTMLBodyElement *This = HTMLBODY_THIS(iface);
399     FIXME("(%p)->(%p)\n", This, p);
400     return E_NOTIMPL;
401 }
402
403 static HRESULT WINAPI HTMLBodyElement_createTextRange(IHTMLBodyElement *iface, IHTMLTxtRange **range)
404 {
405     HTMLBodyElement *This = HTMLBODY_THIS(iface);
406     nsIDOMRange *nsrange = NULL;
407
408     TRACE("(%p)->(%p)\n", This, range);
409
410     if(This->textcont.element.node.doc->nscontainer) {
411         nsIDOMDocument *nsdoc;
412         nsIDOMDocumentRange *nsdocrange;
413         nsresult nsres;
414
415         nsIWebNavigation_GetDocument(This->textcont.element.node.doc->nscontainer->navigation, &nsdoc);
416         nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMDocumentRange, (void**)&nsdocrange);
417         nsIDOMDocument_Release(nsdoc);
418
419         nsres = nsIDOMDocumentRange_CreateRange(nsdocrange, &nsrange);
420         if(NS_SUCCEEDED(nsres)) {
421             nsres = nsIDOMRange_SelectNodeContents(nsrange, This->textcont.element.node.nsnode);
422             if(NS_FAILED(nsres))
423                 ERR("SelectNodeContents failed: %08x\n", nsres);
424         }else {
425             ERR("CreateRange failed: %08x\n", nsres);
426         }
427
428         nsIDOMDocumentRange_Release(nsdocrange);
429     }
430
431     *range = HTMLTxtRange_Create(This->textcont.element.node.doc, nsrange);
432     return S_OK;
433 }
434
435 static void HTMLBodyElement_destructor(IUnknown *iface)
436 {
437     HTMLBodyElement *This = HTMLBODY_THIS(iface);
438
439     ConnectionPointContainer_Destroy(&This->cp_container);
440     nsIDOMHTMLBodyElement_Release(This->nsbody);
441     mshtml_free(This);
442 }
443
444 static const IHTMLBodyElementVtbl HTMLBodyElementVtbl = {
445     HTMLBodyElement_QueryInterface,
446     HTMLBodyElement_AddRef,
447     HTMLBodyElement_Release,
448     HTMLBodyElement_GetTypeInfoCount,
449     HTMLBodyElement_GetTypeInfo,
450     HTMLBodyElement_GetIDsOfNames,
451     HTMLBodyElement_Invoke,
452     HTMLBodyElement_put_background,
453     HTMLBodyElement_get_background,
454     HTMLBodyElement_put_bgProperties,
455     HTMLBodyElement_get_bgProperties,
456     HTMLBodyElement_put_leftMargin,
457     HTMLBodyElement_get_leftMargin,
458     HTMLBodyElement_put_topMargin,
459     HTMLBodyElement_get_topMargin,
460     HTMLBodyElement_put_rightMargin,
461     HTMLBodyElement_get_rightMargin,
462     HTMLBodyElement_put_bottomMargin,
463     HTMLBodyElement_get_bottomMargin,
464     HTMLBodyElement_put_noWrap,
465     HTMLBodyElement_get_noWrap,
466     HTMLBodyElement_put_bgColor,
467     HTMLBodyElement_get_bgColor,
468     HTMLBodyElement_put_text,
469     HTMLBodyElement_get_text,
470     HTMLBodyElement_put_link,
471     HTMLBodyElement_get_link,
472     HTMLBodyElement_put_vLink,
473     HTMLBodyElement_get_vLink,
474     HTMLBodyElement_put_aLink,
475     HTMLBodyElement_get_aLink,
476     HTMLBodyElement_put_onload,
477     HTMLBodyElement_get_onload,
478     HTMLBodyElement_put_onunload,
479     HTMLBodyElement_get_onunload,
480     HTMLBodyElement_put_scroll,
481     HTMLBodyElement_get_scroll,
482     HTMLBodyElement_put_onselect,
483     HTMLBodyElement_get_onselect,
484     HTMLBodyElement_put_onbeforeunload,
485     HTMLBodyElement_get_onbeforeunload,
486     HTMLBodyElement_createTextRange
487 };
488
489 HTMLElement *HTMLBodyElement_Create(nsIDOMHTMLElement *nselem)
490 {
491     HTMLBodyElement *ret = mshtml_alloc(sizeof(HTMLBodyElement));
492     nsresult nsres;
493
494     ret->lpHTMLBodyElementVtbl = &HTMLBodyElementVtbl;
495
496     HTMLTextContainer_Init(&ret->text_container);
497
498     ConnectionPoint_Init(&ret->cp_propnotif, CONPTCONT(&ret->cp_container),
499             &IID_IPropertyNotifySink, NULL);
500     ConnectionPoint_Init(&ret->cp_txtcontevents, CONPTCONT(&ret->cp_container),
501             &DIID_HTMLTextContainerEvents, &ret->cp_propnotif);
502     ConnectionPointContainer_Init(&ret->cp_container, &ret->cp_propnotif, (IUnknown*)HTMLBODY(ret));
503
504     nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLBodyElement,
505                                              (void**)&ret->nsbody);
506     if(NS_FAILED(nsres))
507         ERR("Could not get nsDOMHTMLBodyElement: %08x\n", nsres);
508
509     ret->textcont.element.impl = (IUnknown*)HTMLBODY(ret);
510     ret->textcont.element.destructor = HTMLBodyElement_destructor;
511
512     return &ret->textcont.element;
513 }