rpcrt4: Check for integer overflows when increasing the buffer length.
[wine] / dlls / shdocvw / webbrowser.c
1 /*
2  * Implementation of IWebBrowser interface for WebBrowser control
3  *
4  * Copyright 2001 John R. Sheets (for CodeWeavers)
5  * Copyright 2005 Jacek Caban
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include "wine/debug.h"
23 #include "shdocvw.h"
24 #include "exdispid.h"
25
26 WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
27
28 /**********************************************************************
29  * Implement the IWebBrowser interface
30  */
31
32 #define WEBBROWSER_THIS(iface) DEFINE_THIS(WebBrowser, WebBrowser2, iface)
33
34 static HRESULT WINAPI WebBrowser_QueryInterface(IWebBrowser2 *iface, REFIID riid, LPVOID *ppv)
35 {
36     WebBrowser *This = WEBBROWSER_THIS(iface);
37
38     if (ppv == NULL)
39         return E_POINTER;
40     *ppv = NULL;
41
42     if(IsEqualGUID(&IID_IUnknown, riid)) {
43         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
44         *ppv = WEBBROWSER(This);
45     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
46         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
47         *ppv = WEBBROWSER(This);
48     }else if(IsEqualGUID(&IID_IWebBrowser, riid)) {
49         TRACE("(%p)->(IID_IWebBrowser %p)\n", This, ppv);
50         *ppv = WEBBROWSER(This);
51     }else if(IsEqualGUID(&IID_IWebBrowserApp, riid)) {
52         TRACE("(%p)->(IID_IWebBrowserApp %p)\n", This, ppv);
53         *ppv = WEBBROWSER(This);
54     }else if(IsEqualGUID(&IID_IWebBrowser2, riid)) {
55         TRACE("(%p)->(IID_IWebBrowser2 %p)\n", This, ppv);
56         *ppv = WEBBROWSER(This);
57     }else if(IsEqualGUID(&IID_IOleObject, riid)) {
58         TRACE("(%p)->(IID_IOleObject %p)\n", This, ppv);
59         *ppv = OLEOBJ(This);
60     }else if(IsEqualGUID(&IID_IOleWindow, riid)) {
61         TRACE("(%p)->(IID_IOleWindow %p)\n", This, ppv);
62         *ppv = INPLACEOBJ(This);
63     }else if(IsEqualGUID (&IID_IOleInPlaceObject, riid)) {
64         TRACE("(%p)->(IID_IOleInPlaceObject %p)\n", This, ppv);
65         *ppv = INPLACEOBJ(This);
66     }else if(IsEqualGUID(&IID_IOleControl, riid)) {
67         TRACE("(%p)->(IID_IOleControl %p)\n", This, ppv);
68         *ppv = CONTROL(This);
69     }else if(IsEqualGUID(&IID_IPersist, riid)) {
70         TRACE("(%p)->(IID_IPersist %p)\n", This, ppv);
71         *ppv = PERSTORAGE(This);
72     }else if(IsEqualGUID(&IID_IPersistStorage, riid)) {
73         TRACE("(%p)->(IID_IPersistStorage %p)\n", This, ppv);
74         *ppv = PERSTORAGE(This);
75     }else if(IsEqualGUID(&IID_IPersistMemory, riid)) {
76         TRACE("(%p)->(IID_IPersistStorage %p)\n", This, ppv);
77         *ppv = PERMEMORY(This);
78     }else if(IsEqualGUID (&IID_IPersistStreamInit, riid)) {
79         TRACE("(%p)->(IID_IPersistStreamInit %p)\n", This, ppv);
80         *ppv = PERSTRINIT(This);
81     }else if(IsEqualGUID(&IID_IProvideClassInfo, riid)) {
82         TRACE("(%p)->(IID_IProvideClassInfo %p)\n", This, ppv);
83         *ppv = CLASSINFO(This);
84     }else if(IsEqualGUID(&IID_IProvideClassInfo2, riid)) {
85         TRACE("(%p)->(IID_IProvideClassInfo2 %p)\n", This, ppv);
86         *ppv = CLASSINFO(This);
87     }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
88         TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
89         *ppv = CONPTCONT(&This->doc_host.cps);
90     }else if(IsEqualGUID(&IID_IViewObject, riid)) {
91         TRACE("(%p)->(IID_IViewObject %p)\n", This, ppv);
92         *ppv = VIEWOBJ(This);
93     }else if(IsEqualGUID(&IID_IViewObject2, riid)) {
94         TRACE("(%p)->(IID_IViewObject2 %p)\n", This, ppv);
95         *ppv = VIEWOBJ2(This);
96     }else if(IsEqualGUID(&IID_IOleInPlaceActiveObject, riid)) {
97         TRACE("(%p)->(IID_IOleInPlaceActiveObject %p)\n", This, ppv);
98         *ppv = ACTIVEOBJ(This);
99     }else if(IsEqualGUID(&IID_IOleCommandTarget, riid)) {
100         TRACE("(%p)->(IID_IOleCommandTarget %p)\n", This, ppv);
101         *ppv = OLECMD(This);
102     }else if(IsEqualGUID(&IID_IHlinkFrame, riid)) {
103         TRACE("(%p)->(IID_IHlinkFrame %p)\n", This, ppv);
104         *ppv = HLINKFRAME(This);
105     }else if(IsEqualGUID(&IID_IQuickActivate, riid)) {
106         TRACE("(%p)->(IID_IQuickActivate %p) returning NULL\n", This, ppv);
107         return E_NOINTERFACE;
108     }else if(IsEqualGUID(&IID_IRunnableObject, riid)) {
109         TRACE("(%p)->(IID_IRunnableObject %p) returning NULL\n", This, ppv);
110         return E_NOINTERFACE;
111     }else if(IsEqualGUID(&IID_IPerPropertyBrowsing, riid)) {
112         TRACE("(%p)->(IID_IPerPropertyBrowsing %p) returning NULL\n", This, ppv);
113         return E_NOINTERFACE;
114     }else if(IsEqualGUID(&IID_IOleCache, riid)) {
115         TRACE("(%p)->(IID_IOleCache %p) returning NULL\n", This, ppv);
116         return E_NOINTERFACE;
117     }
118
119     if(*ppv) {
120         IUnknown_AddRef((IUnknown*)*ppv);
121         return S_OK;
122     }
123
124     FIXME("(%p)->(%s %p) interface not supported\n", This, debugstr_guid(riid), ppv);
125     return E_NOINTERFACE;
126 }
127
128 static ULONG WINAPI WebBrowser_AddRef(IWebBrowser2 *iface)
129 {
130     WebBrowser *This = WEBBROWSER_THIS(iface);
131     LONG ref = InterlockedIncrement(&This->ref);
132     TRACE("(%p) ref=%d\n", This, ref);
133     return ref;
134 }
135
136 static ULONG WINAPI WebBrowser_Release(IWebBrowser2 *iface)
137 {
138     WebBrowser *This = WEBBROWSER_THIS(iface);
139     LONG ref = InterlockedDecrement(&This->ref);
140
141     TRACE("(%p) ref=%d\n", This, ref);
142
143     if(!ref) {
144         if(This->doc_host.document)
145             IUnknown_Release(This->doc_host.document);
146
147         DocHost_Release(&This->doc_host);
148
149         WebBrowser_OleObject_Destroy(This);
150
151         heap_free(This);
152         SHDOCVW_UnlockModule();
153     }
154
155     return ref;
156 }
157
158 /* IDispatch methods */
159 static HRESULT WINAPI WebBrowser_GetTypeInfoCount(IWebBrowser2 *iface, UINT *pctinfo)
160 {
161     WebBrowser *This = WEBBROWSER_THIS(iface);
162     FIXME("(%p)->(%p)\n", This, pctinfo);
163     return E_NOTIMPL;
164 }
165
166 static HRESULT WINAPI WebBrowser_GetTypeInfo(IWebBrowser2 *iface, UINT iTInfo, LCID lcid,
167                                      LPTYPEINFO *ppTInfo)
168 {
169     WebBrowser *This = WEBBROWSER_THIS(iface);
170     FIXME("(%p)->(%d %d %p)\n", This, iTInfo, lcid, ppTInfo);
171     return E_NOTIMPL;
172 }
173
174 static HRESULT WINAPI WebBrowser_GetIDsOfNames(IWebBrowser2 *iface, REFIID riid,
175                                        LPOLESTR *rgszNames, UINT cNames,
176                                        LCID lcid, DISPID *rgDispId)
177 {
178     WebBrowser *This = WEBBROWSER_THIS(iface);
179     FIXME("(%p)->(%s %p %d %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
180             lcid, rgDispId);
181     return E_NOTIMPL;
182 }
183
184 static HRESULT WINAPI WebBrowser_Invoke(IWebBrowser2 *iface, DISPID dispIdMember,
185                                 REFIID riid, LCID lcid, WORD wFlags,
186                                 DISPPARAMS *pDispParams, VARIANT *pVarResult,
187                                 EXCEPINFO *pExepInfo, UINT *puArgErr)
188 {
189     WebBrowser *This = WEBBROWSER_THIS(iface);
190     ITypeInfo *typeinfo;
191     HRESULT hres;
192
193     TRACE("(%p)->(%d %s %d %08x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
194             lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
195
196     hres = get_typeinfo(&typeinfo);
197     if(FAILED(hres))
198         return hres;
199
200     return ITypeInfo_Invoke(typeinfo, WEBBROWSER2(This), dispIdMember, wFlags, pDispParams,
201                             pVarResult, pExepInfo, puArgErr);
202 }
203
204 /* IWebBrowser methods */
205 static HRESULT WINAPI WebBrowser_GoBack(IWebBrowser2 *iface)
206 {
207     WebBrowser *This = WEBBROWSER_THIS(iface);
208     FIXME("(%p)\n", This);
209     return E_NOTIMPL;
210 }
211
212 static HRESULT WINAPI WebBrowser_GoForward(IWebBrowser2 *iface)
213 {
214     WebBrowser *This = WEBBROWSER_THIS(iface);
215     FIXME("(%p)\n", This);
216     return E_NOTIMPL;
217 }
218
219 static HRESULT WINAPI WebBrowser_GoHome(IWebBrowser2 *iface)
220 {
221     WebBrowser *This = WEBBROWSER_THIS(iface);
222     TRACE("(%p)\n", This);
223     return go_home(&This->doc_host);
224 }
225
226 static HRESULT WINAPI WebBrowser_GoSearch(IWebBrowser2 *iface)
227 {
228     WebBrowser *This = WEBBROWSER_THIS(iface);
229     FIXME("(%p)\n", This);
230     return E_NOTIMPL;
231 }
232
233 static HRESULT WINAPI WebBrowser_Navigate(IWebBrowser2 *iface, BSTR szUrl,
234                                   VARIANT *Flags, VARIANT *TargetFrameName,
235                                   VARIANT *PostData, VARIANT *Headers)
236 {
237     WebBrowser *This = WEBBROWSER_THIS(iface);
238
239     TRACE("(%p)->(%s %p %p %p %p)\n", This, debugstr_w(szUrl), Flags, TargetFrameName,
240           PostData, Headers);
241
242     return navigate_url(&This->doc_host, szUrl, Flags, TargetFrameName, PostData, Headers);
243 }
244
245 static HRESULT WINAPI WebBrowser_Refresh(IWebBrowser2 *iface)
246 {
247     WebBrowser *This = WEBBROWSER_THIS(iface);
248     FIXME("(%p)\n", This);
249     return E_NOTIMPL;
250 }
251
252 static HRESULT WINAPI WebBrowser_Refresh2(IWebBrowser2 *iface, VARIANT *Level)
253 {
254     WebBrowser *This = WEBBROWSER_THIS(iface);
255     FIXME("(%p)->(%p)\n", This, Level);
256     return E_NOTIMPL;
257 }
258
259 static HRESULT WINAPI WebBrowser_Stop(IWebBrowser2 *iface)
260 {
261     WebBrowser *This = WEBBROWSER_THIS(iface);
262     FIXME("(%p)\n", This);
263     return E_NOTIMPL;
264 }
265
266 static HRESULT WINAPI WebBrowser_get_Application(IWebBrowser2 *iface, IDispatch **ppDisp)
267 {
268     WebBrowser *This = WEBBROWSER_THIS(iface);
269
270     TRACE("(%p)->(%p)\n", This, ppDisp);
271
272     if(!ppDisp)
273         return E_POINTER;
274
275     *ppDisp = (IDispatch*)WEBBROWSER2(This);
276     IDispatch_AddRef(*ppDisp);
277     return S_OK;
278 }
279
280 static HRESULT WINAPI WebBrowser_get_Parent(IWebBrowser2 *iface, IDispatch **ppDisp)
281 {
282     WebBrowser *This = WEBBROWSER_THIS(iface);
283     FIXME("(%p)->(%p)\n", This, ppDisp);
284     return E_NOTIMPL;
285 }
286
287 static HRESULT WINAPI WebBrowser_get_Container(IWebBrowser2 *iface, IDispatch **ppDisp)
288 {
289     WebBrowser *This = WEBBROWSER_THIS(iface);
290     FIXME("(%p)->(%p)\n", This, ppDisp);
291     return E_NOTIMPL;
292 }
293
294 static HRESULT WINAPI WebBrowser_get_Document(IWebBrowser2 *iface, IDispatch **ppDisp)
295 {
296     WebBrowser *This = WEBBROWSER_THIS(iface);
297
298     TRACE("(%p)->(%p)\n", This, ppDisp);
299
300     *ppDisp = NULL;
301     if(This->doc_host.document)
302         IUnknown_QueryInterface(This->doc_host.document, &IID_IDispatch, (void**)ppDisp);
303
304     return S_OK;
305 }
306
307 static HRESULT WINAPI WebBrowser_get_TopLevelContainer(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
308 {
309     WebBrowser *This = WEBBROWSER_THIS(iface);
310     FIXME("(%p)->(%p)\n", This, pBool);
311     return E_NOTIMPL;
312 }
313
314 static HRESULT WINAPI WebBrowser_get_Type(IWebBrowser2 *iface, BSTR *Type)
315 {
316     WebBrowser *This = WEBBROWSER_THIS(iface);
317     FIXME("(%p)->(%p)\n", This, Type);
318     return E_NOTIMPL;
319 }
320
321 static HRESULT WINAPI WebBrowser_get_Left(IWebBrowser2 *iface, long *pl)
322 {
323     WebBrowser *This = WEBBROWSER_THIS(iface);
324
325     TRACE("(%p)->(%p)\n", This, pl);
326
327     *pl = This->pos_rect.left;
328     return S_OK;
329 }
330
331 static HRESULT WINAPI WebBrowser_put_Left(IWebBrowser2 *iface, long Left)
332 {
333     WebBrowser *This = WEBBROWSER_THIS(iface);
334     RECT rect;
335
336     TRACE("(%p)->(%ld)\n", This, Left);
337
338     if(!This->inplace)
339         return E_UNEXPECTED;
340
341     memcpy(&rect, &This->pos_rect, sizeof(RECT));
342     rect.left = Left;
343
344     /* We don't really change the window position here.
345      * We just notify the embedder that he should do so. */
346     return IOleInPlaceSite_OnPosRectChange(This->inplace, &rect);
347 }
348
349 static HRESULT WINAPI WebBrowser_get_Top(IWebBrowser2 *iface, long *pl)
350 {
351     WebBrowser *This = WEBBROWSER_THIS(iface);
352
353     TRACE("(%p)->(%p)\n", This, pl);
354
355     *pl = This->pos_rect.top;
356     return S_OK;
357 }
358
359 static HRESULT WINAPI WebBrowser_put_Top(IWebBrowser2 *iface, long Top)
360 {
361     WebBrowser *This = WEBBROWSER_THIS(iface);
362     RECT rect;
363
364     TRACE("(%p)->(%ld)\n", This, Top);
365
366     if(!This->inplace)
367         return E_UNEXPECTED;
368
369     memcpy(&rect, &This->pos_rect, sizeof(RECT));
370     rect.top = Top;
371
372     /* We don't really change the window position here.
373      * We just notify the embedder that he should do so. */
374     return IOleInPlaceSite_OnPosRectChange(This->inplace, &rect);
375 }
376
377 static HRESULT WINAPI WebBrowser_get_Width(IWebBrowser2 *iface, long *pl)
378 {
379     WebBrowser *This = WEBBROWSER_THIS(iface);
380
381     TRACE("(%p)->(%p)\n", This, pl);
382
383     *pl = This->pos_rect.right - This->pos_rect.left;
384     return S_OK;
385 }
386
387 static HRESULT WINAPI WebBrowser_put_Width(IWebBrowser2 *iface, long Width)
388 {
389     WebBrowser *This = WEBBROWSER_THIS(iface);
390     RECT rect;
391
392     TRACE("(%p)->(%ld)\n", This, Width);
393
394     if(!This->inplace)
395         return E_UNEXPECTED;
396
397     memcpy(&rect, &This->pos_rect, sizeof(RECT));
398     rect.right = rect.left+Width;
399  
400     /* We don't really change the window size here.
401      * We just notify the embedder that he should do so. */
402    return IOleInPlaceSite_OnPosRectChange(This->inplace, &rect);
403 }
404
405 static HRESULT WINAPI WebBrowser_get_Height(IWebBrowser2 *iface, long *pl)
406 {
407     WebBrowser *This = WEBBROWSER_THIS(iface);
408
409     TRACE("(%p)->(%p)\n", This, pl);
410
411     *pl = This->pos_rect.bottom - This->pos_rect.top;
412     return S_OK;
413 }
414
415 static HRESULT WINAPI WebBrowser_put_Height(IWebBrowser2 *iface, long Height)
416 {
417     WebBrowser *This = WEBBROWSER_THIS(iface);
418     RECT rect;
419
420     TRACE("(%p)->(%ld)\n", This, Height);
421
422     if(!This->inplace)
423         return E_UNEXPECTED;
424
425     memcpy(&rect, &This->pos_rect, sizeof(RECT));
426     rect.bottom = rect.top+Height;
427
428     /* We don't really change the window size here.
429      * We just notify the embedder that he should do so. */
430     return IOleInPlaceSite_OnPosRectChange(This->inplace, &rect);
431 }
432
433 static HRESULT WINAPI WebBrowser_get_LocationName(IWebBrowser2 *iface, BSTR *LocationName)
434 {
435     WebBrowser *This = WEBBROWSER_THIS(iface);
436     FIXME("(%p)->(%p)\n", This, LocationName);
437     return E_NOTIMPL;
438 }
439
440 static HRESULT WINAPI WebBrowser_get_LocationURL(IWebBrowser2 *iface, BSTR *LocationURL)
441 {
442     WebBrowser *This = WEBBROWSER_THIS(iface);
443
444     FIXME("(%p)->(%p)\n", This, LocationURL);
445
446     if(!This->doc_host.url) {
447         static const WCHAR null_char = 0;
448         *LocationURL = SysAllocString(&null_char);
449         return S_FALSE;
450     }
451
452     *LocationURL = SysAllocString(This->doc_host.url);
453     return S_OK;
454 }
455
456 static HRESULT WINAPI WebBrowser_get_Busy(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
457 {
458     WebBrowser *This = WEBBROWSER_THIS(iface);
459     FIXME("(%p)->(%p)\n", This, pBool);
460     return E_NOTIMPL;
461 }
462
463 static HRESULT WINAPI WebBrowser_Quit(IWebBrowser2 *iface)
464 {
465     WebBrowser *This = WEBBROWSER_THIS(iface);
466
467     TRACE("(%p)\n", This);
468
469     /* It's a InternetExplorer specific method, we have nothing to do here. */
470     return E_FAIL;
471 }
472
473 static HRESULT WINAPI WebBrowser_ClientToWindow(IWebBrowser2 *iface, int *pcx, int *pcy)
474 {
475     WebBrowser *This = WEBBROWSER_THIS(iface);
476     FIXME("(%p)->(%p %p)\n", This, pcx, pcy);
477     return E_NOTIMPL;
478 }
479
480 static HRESULT WINAPI WebBrowser_PutProperty(IWebBrowser2 *iface, BSTR szProperty, VARIANT vtValue)
481 {
482     WebBrowser *This = WEBBROWSER_THIS(iface);
483     FIXME("(%p)->(%s)\n", This, debugstr_w(szProperty));
484     return E_NOTIMPL;
485 }
486
487 static HRESULT WINAPI WebBrowser_GetProperty(IWebBrowser2 *iface, BSTR szProperty, VARIANT *pvtValue)
488 {
489     WebBrowser *This = WEBBROWSER_THIS(iface);
490     FIXME("(%p)->(%s %p)\n", This, debugstr_w(szProperty), pvtValue);
491     return E_NOTIMPL;
492 }
493
494 static HRESULT WINAPI WebBrowser_get_Name(IWebBrowser2 *iface, BSTR *Name)
495 {
496     WebBrowser *This = WEBBROWSER_THIS(iface);
497     FIXME("(%p)->(%p)\n", This, Name);
498     return E_NOTIMPL;
499 }
500
501 static HRESULT WINAPI WebBrowser_get_HWND(IWebBrowser2 *iface, long *pHWND)
502 {
503     WebBrowser *This = WEBBROWSER_THIS(iface);
504
505     TRACE("(%p)->(%p)\n", This, pHWND);
506
507     /* WebBrowser control never has a frame window (in opposition to InternetExplorer) */
508     *pHWND = 0;
509     return E_FAIL;
510 }
511
512 static HRESULT WINAPI WebBrowser_get_FullName(IWebBrowser2 *iface, BSTR *FullName)
513 {
514     WebBrowser *This = WEBBROWSER_THIS(iface);
515     FIXME("(%p)->(%p)\n", This, FullName);
516     return E_NOTIMPL;
517 }
518
519 static HRESULT WINAPI WebBrowser_get_Path(IWebBrowser2 *iface, BSTR *Path)
520 {
521     WebBrowser *This = WEBBROWSER_THIS(iface);
522     FIXME("(%p)->(%p)\n", This, Path);
523     return E_NOTIMPL;
524 }
525
526 static HRESULT WINAPI WebBrowser_get_Visible(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
527 {
528     WebBrowser *This = WEBBROWSER_THIS(iface);
529
530     TRACE("(%p)->(%p)\n", This, pBool);
531
532     *pBool = This->visible;
533     return S_OK;
534 }
535
536 static HRESULT WINAPI WebBrowser_put_Visible(IWebBrowser2 *iface, VARIANT_BOOL Value)
537 {
538     WebBrowser *This = WEBBROWSER_THIS(iface);
539     VARIANTARG arg;
540     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
541
542     TRACE("(%p)->(%x)\n", This, Value);
543
544     This->visible = Value;
545
546     V_VT(&arg) = VT_BOOL;
547     V_BOOL(&arg) = Value;
548     call_sink(This->doc_host.cps.wbe2, DISPID_ONVISIBLE, &dispparams);
549
550     return S_OK;
551 }
552
553 static HRESULT WINAPI WebBrowser_get_StatusBar(IWebBrowser2 *iface, VARIANT_BOOL *pBool)
554 {
555     WebBrowser *This = WEBBROWSER_THIS(iface);
556
557     TRACE("(%p)->(%p)\n", This, pBool);
558
559     *pBool = This->status_bar;
560     return S_OK;
561 }
562
563 static HRESULT WINAPI WebBrowser_put_StatusBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
564 {
565     WebBrowser *This = WEBBROWSER_THIS(iface);
566     VARIANTARG arg;
567     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
568
569     TRACE("(%p)->(%x)\n", This, Value);
570
571     This->status_bar = Value ? VARIANT_TRUE : VARIANT_FALSE;
572
573     /* In opposition to InternetExplorer, all we should do here is
574      * inform the embedder about the status bar change. */
575
576     V_VT(&arg) = VT_BOOL;
577     V_BOOL(&arg) = Value;
578     call_sink(This->doc_host.cps.wbe2, DISPID_ONSTATUSBAR, &dispparams);
579
580     return S_OK;
581 }
582
583 static HRESULT WINAPI WebBrowser_get_StatusText(IWebBrowser2 *iface, BSTR *StatusText)
584 {
585     WebBrowser *This = WEBBROWSER_THIS(iface);
586     FIXME("(%p)->(%p)\n", This, StatusText);
587     return E_NOTIMPL;
588 }
589
590 static HRESULT WINAPI WebBrowser_put_StatusText(IWebBrowser2 *iface, BSTR StatusText)
591 {
592     WebBrowser *This = WEBBROWSER_THIS(iface);
593     FIXME("(%p)->(%s)\n", This, debugstr_w(StatusText));
594     return E_NOTIMPL;
595 }
596
597 static HRESULT WINAPI WebBrowser_get_ToolBar(IWebBrowser2 *iface, int *Value)
598 {
599     WebBrowser *This = WEBBROWSER_THIS(iface);
600
601     TRACE("(%p)->(%p)\n", This, Value);
602
603     *Value = This->tool_bar;
604     return S_OK;
605 }
606
607 static HRESULT WINAPI WebBrowser_put_ToolBar(IWebBrowser2 *iface, int Value)
608 {
609     WebBrowser *This = WEBBROWSER_THIS(iface);
610     VARIANTARG arg;
611     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
612
613     TRACE("(%p)->(%x)\n", This, Value);
614
615     This->tool_bar = Value ? VARIANT_TRUE : VARIANT_FALSE;
616
617     /* In opposition to InternetExplorer, all we should do here is
618      * inform the embedder about the tool bar change. */
619
620     V_VT(&arg) = VT_BOOL;
621     V_BOOL(&arg) = Value;
622     call_sink(This->doc_host.cps.wbe2, DISPID_ONTOOLBAR, &dispparams);
623
624     return S_OK;
625 }
626
627 static HRESULT WINAPI WebBrowser_get_MenuBar(IWebBrowser2 *iface, VARIANT_BOOL *Value)
628 {
629     WebBrowser *This = WEBBROWSER_THIS(iface);
630
631     TRACE("(%p)->(%p)\n", This, Value);
632
633     *Value = This->menu_bar;
634     return S_OK;
635 }
636
637 static HRESULT WINAPI WebBrowser_put_MenuBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
638 {
639     WebBrowser *This = WEBBROWSER_THIS(iface);
640     VARIANTARG arg;
641     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
642
643     TRACE("(%p)->(%x)\n", This, Value);
644
645     This->menu_bar = Value ? VARIANT_TRUE : VARIANT_FALSE;
646
647     /* In opposition to InternetExplorer, all we should do here is
648      * inform the embedder about the menu bar change. */
649
650     V_VT(&arg) = VT_BOOL;
651     V_BOOL(&arg) = Value;
652     call_sink(This->doc_host.cps.wbe2, DISPID_ONMENUBAR, &dispparams);
653
654     return S_OK;
655 }
656
657 static HRESULT WINAPI WebBrowser_get_FullScreen(IWebBrowser2 *iface, VARIANT_BOOL *pbFullScreen)
658 {
659     WebBrowser *This = WEBBROWSER_THIS(iface);
660
661     TRACE("(%p)->(%p)\n", This, pbFullScreen);
662
663     *pbFullScreen = This->full_screen;
664     return S_OK;
665 }
666
667 static HRESULT WINAPI WebBrowser_put_FullScreen(IWebBrowser2 *iface, VARIANT_BOOL bFullScreen)
668 {
669     WebBrowser *This = WEBBROWSER_THIS(iface);
670
671     TRACE("(%p)->(%x)\n", This, bFullScreen);
672
673     This->full_screen = bFullScreen ? VARIANT_TRUE : VARIANT_FALSE;
674     return S_OK;
675 }
676
677 static HRESULT WINAPI WebBrowser_Navigate2(IWebBrowser2 *iface, VARIANT *URL, VARIANT *Flags,
678         VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
679 {
680     WebBrowser *This = WEBBROWSER_THIS(iface);
681
682     TRACE("(%p)->(%p %p %p %p %p)\n", This, URL, Flags, TargetFrameName, PostData, Headers);
683
684     if(!This->client)
685         return E_FAIL;
686
687     if(!URL)
688         return S_OK;
689
690     if(V_VT(URL) != VT_BSTR) {
691         FIXME("Unsupported V_VT(URL) %d\n", V_VT(URL));
692         return E_INVALIDARG;
693     }
694
695     return navigate_url(&This->doc_host, V_BSTR(URL), Flags, TargetFrameName, PostData, Headers);
696 }
697
698 static HRESULT WINAPI WebBrowser_QueryStatusWB(IWebBrowser2 *iface, OLECMDID cmdID, OLECMDF *pcmdf)
699 {
700     WebBrowser *This = WEBBROWSER_THIS(iface);
701     FIXME("(%p)->(%d %p)\n", This, cmdID, pcmdf);
702     return E_NOTIMPL;
703 }
704
705 static HRESULT WINAPI WebBrowser_ExecWB(IWebBrowser2 *iface, OLECMDID cmdID,
706         OLECMDEXECOPT cmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
707 {
708     WebBrowser *This = WEBBROWSER_THIS(iface);
709     FIXME("(%p)->(%d %d %p %p)\n", This, cmdID, cmdexecopt, pvaIn, pvaOut);
710     return E_NOTIMPL;
711 }
712
713 static HRESULT WINAPI WebBrowser_ShowBrowserBar(IWebBrowser2 *iface, VARIANT *pvaClsid,
714         VARIANT *pvarShow, VARIANT *pvarSize)
715 {
716     WebBrowser *This = WEBBROWSER_THIS(iface);
717     FIXME("(%p)->(%p %p %p)\n", This, pvaClsid, pvarShow, pvarSize);
718     return E_NOTIMPL;
719 }
720
721 static HRESULT WINAPI WebBrowser_get_ReadyState(IWebBrowser2 *iface, READYSTATE *lpReadyState)
722 {
723     WebBrowser *This = WEBBROWSER_THIS(iface);
724     FIXME("(%p)->(%p)\n", This, lpReadyState);
725     return E_NOTIMPL;
726 }
727
728 static HRESULT WINAPI WebBrowser_get_Offline(IWebBrowser2 *iface, VARIANT_BOOL *pbOffline)
729 {
730     WebBrowser *This = WEBBROWSER_THIS(iface);
731
732     TRACE("(%p)->(%p)\n", This, pbOffline);
733
734     *pbOffline = This->doc_host.offline;
735     return S_OK;
736 }
737
738 static HRESULT WINAPI WebBrowser_put_Offline(IWebBrowser2 *iface, VARIANT_BOOL bOffline)
739 {
740     WebBrowser *This = WEBBROWSER_THIS(iface);
741
742     TRACE("(%p)->(%x)\n", This, bOffline);
743
744     This->doc_host.offline = bOffline ? VARIANT_TRUE : VARIANT_FALSE;
745     return S_OK;
746 }
747
748 static HRESULT WINAPI WebBrowser_get_Silent(IWebBrowser2 *iface, VARIANT_BOOL *pbSilent)
749 {
750     WebBrowser *This = WEBBROWSER_THIS(iface);
751
752     TRACE("(%p)->(%p)\n", This, pbSilent);
753
754     *pbSilent = This->doc_host.silent;
755     return S_OK;
756 }
757
758 static HRESULT WINAPI WebBrowser_put_Silent(IWebBrowser2 *iface, VARIANT_BOOL bSilent)
759 {
760     WebBrowser *This = WEBBROWSER_THIS(iface);
761
762     TRACE("(%p)->(%x)\n", This, bSilent);
763
764     This->doc_host.silent = bSilent ? VARIANT_TRUE : VARIANT_FALSE;
765     return S_OK;
766 }
767
768 static HRESULT WINAPI WebBrowser_get_RegisterAsBrowser(IWebBrowser2 *iface,
769         VARIANT_BOOL *pbRegister)
770 {
771     WebBrowser *This = WEBBROWSER_THIS(iface);
772     FIXME("(%p)->(%p)\n", This, pbRegister);
773     return E_NOTIMPL;
774 }
775
776 static HRESULT WINAPI WebBrowser_put_RegisterAsBrowser(IWebBrowser2 *iface,
777         VARIANT_BOOL bRegister)
778 {
779     WebBrowser *This = WEBBROWSER_THIS(iface);
780     FIXME("(%p)->(%x)\n", This, bRegister);
781     return E_NOTIMPL;
782 }
783
784 static HRESULT WINAPI WebBrowser_get_RegisterAsDropTarget(IWebBrowser2 *iface,
785         VARIANT_BOOL *pbRegister)
786 {
787     WebBrowser *This = WEBBROWSER_THIS(iface);
788     FIXME("(%p)->(%p)\n", This, pbRegister);
789     return E_NOTIMPL;
790 }
791
792 static HRESULT WINAPI WebBrowser_put_RegisterAsDropTarget(IWebBrowser2 *iface,
793         VARIANT_BOOL bRegister)
794 {
795     WebBrowser *This = WEBBROWSER_THIS(iface);
796     FIXME("(%p)->(%x)\n", This, bRegister);
797     return S_OK;
798 }
799
800 static HRESULT WINAPI WebBrowser_get_TheaterMode(IWebBrowser2 *iface, VARIANT_BOOL *pbRegister)
801 {
802     WebBrowser *This = WEBBROWSER_THIS(iface);
803     FIXME("(%p)->(%p)\n", This, pbRegister);
804     return E_NOTIMPL;
805 }
806
807 static HRESULT WINAPI WebBrowser_put_TheaterMode(IWebBrowser2 *iface, VARIANT_BOOL bRegister)
808 {
809     WebBrowser *This = WEBBROWSER_THIS(iface);
810     FIXME("(%p)->(%x)\n", This, bRegister);
811     return E_NOTIMPL;
812 }
813
814 static HRESULT WINAPI WebBrowser_get_AddressBar(IWebBrowser2 *iface, VARIANT_BOOL *Value)
815 {
816     WebBrowser *This = WEBBROWSER_THIS(iface);
817
818     TRACE("(%p)->(%p)\n", This, Value);
819
820     *Value = This->address_bar;
821     return S_OK;
822 }
823
824 static HRESULT WINAPI WebBrowser_put_AddressBar(IWebBrowser2 *iface, VARIANT_BOOL Value)
825 {
826     WebBrowser *This = WEBBROWSER_THIS(iface);
827     VARIANTARG arg;
828     DISPPARAMS dispparams = {&arg, NULL, 1, 0};
829
830     TRACE("(%p)->(%x)\n", This, Value);
831
832     This->address_bar = Value ? VARIANT_TRUE : VARIANT_FALSE;
833
834     /* In opposition to InternetExplorer, all we should do here is
835      * inform the embedder about the address bar change. */
836
837     V_VT(&arg) = VT_BOOL;
838     V_BOOL(&arg) = Value;
839     call_sink(This->doc_host.cps.wbe2, DISPID_ONADDRESSBAR, &dispparams);
840
841     return S_OK;
842 }
843
844 static HRESULT WINAPI WebBrowser_get_Resizable(IWebBrowser2 *iface, VARIANT_BOOL *Value)
845 {
846     WebBrowser *This = WEBBROWSER_THIS(iface);
847
848     TRACE("(%p)->(%p)\n", This, Value);
849
850     /* It's InternetExplorer object's method. We have nothing to do here. */
851     return E_NOTIMPL;
852 }
853
854 static HRESULT WINAPI WebBrowser_put_Resizable(IWebBrowser2 *iface, VARIANT_BOOL Value)
855 {
856     WebBrowser *This = WEBBROWSER_THIS(iface);
857
858     TRACE("(%p)->(%x)\n", This, Value);
859
860     /* It's InternetExplorer object's method. We have nothing to do here. */
861     return S_OK;
862 }
863
864 #undef WEBBROWSER_THIS
865
866 static const IWebBrowser2Vtbl WebBrowser2Vtbl =
867 {
868     WebBrowser_QueryInterface,
869     WebBrowser_AddRef,
870     WebBrowser_Release,
871     WebBrowser_GetTypeInfoCount,
872     WebBrowser_GetTypeInfo,
873     WebBrowser_GetIDsOfNames,
874     WebBrowser_Invoke,
875     WebBrowser_GoBack,
876     WebBrowser_GoForward,
877     WebBrowser_GoHome,
878     WebBrowser_GoSearch,
879     WebBrowser_Navigate,
880     WebBrowser_Refresh,
881     WebBrowser_Refresh2,
882     WebBrowser_Stop,
883     WebBrowser_get_Application,
884     WebBrowser_get_Parent,
885     WebBrowser_get_Container,
886     WebBrowser_get_Document,
887     WebBrowser_get_TopLevelContainer,
888     WebBrowser_get_Type,
889     WebBrowser_get_Left,
890     WebBrowser_put_Left,
891     WebBrowser_get_Top,
892     WebBrowser_put_Top,
893     WebBrowser_get_Width,
894     WebBrowser_put_Width,
895     WebBrowser_get_Height,
896     WebBrowser_put_Height,
897     WebBrowser_get_LocationName,
898     WebBrowser_get_LocationURL,
899     WebBrowser_get_Busy,
900     WebBrowser_Quit,
901     WebBrowser_ClientToWindow,
902     WebBrowser_PutProperty,
903     WebBrowser_GetProperty,
904     WebBrowser_get_Name,
905     WebBrowser_get_HWND,
906     WebBrowser_get_FullName,
907     WebBrowser_get_Path,
908     WebBrowser_get_Visible,
909     WebBrowser_put_Visible,
910     WebBrowser_get_StatusBar,
911     WebBrowser_put_StatusBar,
912     WebBrowser_get_StatusText,
913     WebBrowser_put_StatusText,
914     WebBrowser_get_ToolBar,
915     WebBrowser_put_ToolBar,
916     WebBrowser_get_MenuBar,
917     WebBrowser_put_MenuBar,
918     WebBrowser_get_FullScreen,
919     WebBrowser_put_FullScreen,
920     WebBrowser_Navigate2,
921     WebBrowser_QueryStatusWB,
922     WebBrowser_ExecWB,
923     WebBrowser_ShowBrowserBar,
924     WebBrowser_get_ReadyState,
925     WebBrowser_get_Offline,
926     WebBrowser_put_Offline,
927     WebBrowser_get_Silent,
928     WebBrowser_put_Silent,
929     WebBrowser_get_RegisterAsBrowser,
930     WebBrowser_put_RegisterAsBrowser,
931     WebBrowser_get_RegisterAsDropTarget,
932     WebBrowser_put_RegisterAsDropTarget,
933     WebBrowser_get_TheaterMode,
934     WebBrowser_put_TheaterMode,
935     WebBrowser_get_AddressBar,
936     WebBrowser_put_AddressBar,
937     WebBrowser_get_Resizable,
938     WebBrowser_put_Resizable
939 };
940
941 static HRESULT WebBrowser_Create(INT version, IUnknown *pOuter, REFIID riid, void **ppv)
942 {
943     WebBrowser *ret;
944     HRESULT hres;
945
946     TRACE("(%p %s %p) version=%d\n", pOuter, debugstr_guid(riid), ppv, version);
947
948     ret = heap_alloc(sizeof(WebBrowser));
949
950     ret->lpWebBrowser2Vtbl = &WebBrowser2Vtbl;
951     ret->ref = 0;
952     ret->version = version;
953
954     DocHost_Init(&ret->doc_host, (IDispatch*)WEBBROWSER2(ret));
955
956     ret->visible = VARIANT_TRUE;
957     ret->menu_bar = VARIANT_TRUE;
958     ret->address_bar = VARIANT_TRUE;
959     ret->status_bar = VARIANT_TRUE;
960     ret->tool_bar = VARIANT_TRUE;
961     ret->full_screen = VARIANT_FALSE;
962
963     WebBrowser_OleObject_Init(ret);
964     WebBrowser_ViewObject_Init(ret);
965     WebBrowser_Persist_Init(ret);
966     WebBrowser_ClassInfo_Init(ret);
967     WebBrowser_HlinkFrame_Init(ret);
968
969     hres = IWebBrowser_QueryInterface(WEBBROWSER(ret), riid, ppv);
970     if(SUCCEEDED(hres)) {
971         SHDOCVW_LockModule();
972     }else {
973         heap_free(ret);
974         return hres;
975     }
976
977     return hres;
978 }
979
980 HRESULT WebBrowserV1_Create(IUnknown *pOuter, REFIID riid, void **ppv)
981 {
982     return WebBrowser_Create(1, pOuter, riid, ppv);
983 }
984
985 HRESULT WebBrowserV2_Create(IUnknown *pOuter, REFIID riid, void **ppv)
986 {
987     return WebBrowser_Create(2, pOuter, riid, ppv);
988 }