mshtml: Support IObjectIdentity interface in HTMLWindow object.
[wine] / dlls / mshtml / htmlwindow.c
1 /*
2  * Copyright 2006-2012 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 <stdarg.h>
20 #include <assert.h>
21
22 #define COBJMACROS
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "ole2.h"
28 #include "mshtmdid.h"
29 #include "shlguid.h"
30 #include "shobjidl.h"
31 #include "exdispid.h"
32
33 #define NO_SHLWAPI_REG
34 #include "shlwapi.h"
35
36 #include "wine/debug.h"
37
38 #include "mshtml_private.h"
39 #include "htmlevent.h"
40 #include "htmlscript.h"
41 #include "binding.h"
42 #include "resource.h"
43
44 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
45
46 static struct list window_list = LIST_INIT(window_list);
47
48 static inline BOOL is_outer_window(HTMLWindow *window)
49 {
50     return &window->outer_window->base == window;
51 }
52
53 static void release_children(HTMLOuterWindow *This)
54 {
55     HTMLOuterWindow *child;
56
57     while(!list_empty(&This->children)) {
58         child = LIST_ENTRY(list_tail(&This->children), HTMLOuterWindow, sibling_entry);
59
60         list_remove(&child->sibling_entry);
61         child->parent = NULL;
62         IHTMLWindow2_Release(&child->base.IHTMLWindow2_iface);
63     }
64 }
65
66 static HRESULT get_location(HTMLInnerWindow *This, HTMLLocation **ret)
67 {
68     if(This->location) {
69         IHTMLLocation_AddRef(&This->location->IHTMLLocation_iface);
70     }else {
71         HRESULT hres;
72
73         hres = HTMLLocation_Create(This, &This->location);
74         if(FAILED(hres))
75             return hres;
76     }
77
78     *ret = This->location;
79     return S_OK;
80 }
81
82 void get_top_window(HTMLOuterWindow *window, HTMLOuterWindow **ret)
83 {
84     HTMLOuterWindow *iter;
85
86     for(iter = window; iter->parent; iter = iter->parent);
87     *ret = iter;
88 }
89
90 static inline HRESULT set_window_event(HTMLWindow *window, eventid_t eid, VARIANT *var)
91 {
92     if(!window->inner_window->doc) {
93         FIXME("No document\n");
94         return E_FAIL;
95     }
96
97     return set_event_handler(&window->inner_window->doc->body_event_target, NULL, window->inner_window->doc, eid, var);
98 }
99
100 static inline HRESULT get_window_event(HTMLWindow *window, eventid_t eid, VARIANT *var)
101 {
102     if(!window->inner_window->doc) {
103         FIXME("No document\n");
104         return E_FAIL;
105     }
106
107     return get_event_handler(&window->inner_window->doc->body_event_target, eid, var);
108 }
109
110 static void detach_inner_window(HTMLInnerWindow *window)
111 {
112     HTMLOuterWindow *outer_window = window->base.outer_window;
113
114     if(outer_window && outer_window->doc_obj && outer_window == outer_window->doc_obj->basedoc.window)
115         window->doc->basedoc.cp_container.forward_container = NULL;
116
117     if(window->doc)
118         detach_events(window->doc);
119     abort_window_bindings(window);
120     remove_target_tasks(window->task_magic);
121     release_script_hosts(window);
122     window->base.outer_window = NULL;
123
124     if(outer_window && outer_window->base.inner_window == window) {
125         outer_window->base.inner_window = NULL;
126         IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
127     }
128 }
129
130 static inline HTMLWindow *impl_from_IHTMLWindow2(IHTMLWindow2 *iface)
131 {
132     return CONTAINING_RECORD(iface, HTMLWindow, IHTMLWindow2_iface);
133 }
134
135 static HRESULT WINAPI HTMLWindow2_QueryInterface(IHTMLWindow2 *iface, REFIID riid, void **ppv)
136 {
137     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
138
139     *ppv = NULL;
140
141     if(IsEqualGUID(&IID_IUnknown, riid)) {
142         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
143         *ppv = &This->IHTMLWindow2_iface;
144     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
145         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
146         *ppv = &This->IHTMLWindow2_iface;
147     }else if(IsEqualGUID(&IID_IDispatchEx, riid)) {
148         TRACE("(%p)->(IID_IDispatchEx %p)\n", This, ppv);
149         *ppv = &This->IDispatchEx_iface;
150     }else if(IsEqualGUID(&IID_IHTMLFramesCollection2, riid)) {
151         TRACE("(%p)->(IID_IHTMLFramesCollection2 %p)\n", This, ppv);
152         *ppv = &This->IHTMLWindow2_iface;
153     }else if(IsEqualGUID(&IID_IHTMLWindow2, riid)) {
154         TRACE("(%p)->(IID_IHTMLWindow2 %p)\n", This, ppv);
155         *ppv = &This->IHTMLWindow2_iface;
156     }else if(IsEqualGUID(&IID_IHTMLWindow3, riid)) {
157         TRACE("(%p)->(IID_IHTMLWindow3 %p)\n", This, ppv);
158         *ppv = &This->IHTMLWindow3_iface;
159     }else if(IsEqualGUID(&IID_IHTMLWindow4, riid)) {
160         TRACE("(%p)->(IID_IHTMLWindow4 %p)\n", This, ppv);
161         *ppv = &This->IHTMLWindow4_iface;
162     }else if(IsEqualGUID(&IID_IHTMLWindow5, riid)) {
163         TRACE("(%p)->(IID_IHTMLWindow5 %p)\n", This, ppv);
164         *ppv = &This->IHTMLWindow5_iface;
165     }else if(IsEqualGUID(&IID_IHTMLWindow6, riid)) {
166         TRACE("(%p)->(IID_IHTMLWindow6 %p)\n", This, ppv);
167         *ppv = &This->IHTMLWindow6_iface;
168     }else if(IsEqualGUID(&IID_IHTMLPrivateWindow, riid)) {
169         TRACE("(%p)->(IID_IHTMLPrivateWindow %p)\n", This, ppv);
170         *ppv = &This->IHTMLPrivateWindow_iface;
171     }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
172         TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
173         *ppv = &This->IServiceProvider_iface;
174     }else if(IsEqualGUID(&IID_ITravelLogClient, riid)) {
175         TRACE("(%p)->(IID_ITravelLogClient %p)\n", This, ppv);
176         *ppv = &This->ITravelLogClient_iface;
177     }else if(IsEqualGUID(&IID_IObjectIdentity, riid)) {
178         TRACE("(%p)->(IID_IObjectIdentity %p)\n", This, ppv);
179         *ppv = &This->IObjectIdentity_iface;
180     }else if(dispex_query_interface(&This->inner_window->dispex, riid, ppv)) {
181         assert(!*ppv);
182         return E_NOINTERFACE;
183     }
184
185     if(*ppv) {
186         IUnknown_AddRef((IUnknown*)*ppv);
187         return S_OK;
188     }
189
190     WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
191     return E_NOINTERFACE;
192 }
193
194 static ULONG WINAPI HTMLWindow2_AddRef(IHTMLWindow2 *iface)
195 {
196     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
197     LONG ref = InterlockedIncrement(&This->ref);
198
199     TRACE("(%p) ref=%d\n", This, ref);
200
201     return ref;
202 }
203
204 static void release_outer_window(HTMLOuterWindow *This)
205 {
206     if(This->pending_window) {
207         abort_window_bindings(This->pending_window);
208         This->pending_window->base.outer_window = NULL;
209         IHTMLWindow2_Release(&This->pending_window->base.IHTMLWindow2_iface);
210     }
211
212     remove_target_tasks(This->task_magic);
213     set_current_mon(This, NULL, 0);
214     if(This->base.inner_window)
215         detach_inner_window(This->base.inner_window);
216     release_children(This);
217
218     if(This->secmgr)
219         IInternetSecurityManager_Release(This->secmgr);
220
221     if(This->frame_element)
222         This->frame_element->content_window = NULL;
223
224     This->window_ref->window = NULL;
225     windowref_release(This->window_ref);
226
227     if(This->nswindow)
228         nsIDOMWindow_Release(This->nswindow);
229
230     list_remove(&This->entry);
231     heap_free(This);
232 }
233
234 static void release_inner_window(HTMLInnerWindow *This)
235 {
236     unsigned i;
237
238     TRACE("%p\n", This);
239
240     detach_inner_window(This);
241
242     if(This->doc) {
243         This->doc->window = NULL;
244         htmldoc_release(&This->doc->basedoc);
245     }
246
247     release_dispex(&This->dispex);
248
249     for(i=0; i < This->global_prop_cnt; i++)
250         heap_free(This->global_props[i].name);
251     heap_free(This->global_props);
252
253     if(This->location) {
254         This->location->window = NULL;
255         IHTMLLocation_Release(&This->location->IHTMLLocation_iface);
256     }
257
258     if(This->image_factory) {
259         This->image_factory->window = NULL;
260         IHTMLImageElementFactory_Release(&This->image_factory->IHTMLImageElementFactory_iface);
261     }
262
263     if(This->option_factory) {
264         This->option_factory->window = NULL;
265         IHTMLOptionElementFactory_Release(&This->option_factory->IHTMLOptionElementFactory_iface);
266     }
267
268     if(This->screen)
269         IHTMLScreen_Release(This->screen);
270
271     if(This->history) {
272         This->history->window = NULL;
273         IOmHistory_Release(&This->history->IOmHistory_iface);
274     }
275
276     if(This->mon)
277         IMoniker_Release(This->mon);
278
279     heap_free(This);
280 }
281
282 static ULONG WINAPI HTMLWindow2_Release(IHTMLWindow2 *iface)
283 {
284     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
285     LONG ref = InterlockedDecrement(&This->ref);
286
287     TRACE("(%p) ref=%d\n", This, ref);
288
289     if(!ref) {
290         if(is_outer_window(This))
291             release_outer_window(This->outer_window);
292         else
293             release_inner_window(This->inner_window);
294     }
295
296     return ref;
297 }
298
299 static HRESULT WINAPI HTMLWindow2_GetTypeInfoCount(IHTMLWindow2 *iface, UINT *pctinfo)
300 {
301     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
302
303     return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo);
304 }
305
306 static HRESULT WINAPI HTMLWindow2_GetTypeInfo(IHTMLWindow2 *iface, UINT iTInfo,
307                                               LCID lcid, ITypeInfo **ppTInfo)
308 {
309     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
310
311     return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo);
312 }
313
314 static HRESULT WINAPI HTMLWindow2_GetIDsOfNames(IHTMLWindow2 *iface, REFIID riid,
315                                                 LPOLESTR *rgszNames, UINT cNames,
316                                                 LCID lcid, DISPID *rgDispId)
317 {
318     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
319
320     return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid,
321             rgDispId);
322 }
323
324 static HRESULT WINAPI HTMLWindow2_Invoke(IHTMLWindow2 *iface, DISPID dispIdMember,
325                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
326                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
327 {
328     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
329
330     return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
331             pDispParams, pVarResult, pExcepInfo, puArgErr);
332 }
333
334 static HRESULT get_frame_by_index(HTMLOuterWindow *This, UINT32 index, HTMLOuterWindow **ret)
335 {
336     nsIDOMWindowCollection *nsframes;
337     nsIDOMWindow *nswindow;
338     UINT32 length;
339     nsresult nsres;
340
341     nsres = nsIDOMWindow_GetFrames(This->nswindow, &nsframes);
342     if(NS_FAILED(nsres)) {
343         FIXME("nsIDOMWindow_GetFrames failed: 0x%08x\n", nsres);
344         return E_FAIL;
345     }
346
347     nsres = nsIDOMWindowCollection_GetLength(nsframes, &length);
348     assert(nsres == NS_OK);
349
350     if(index >= length) {
351         nsIDOMWindowCollection_Release(nsframes);
352         return DISP_E_MEMBERNOTFOUND;
353     }
354
355     nsres = nsIDOMWindowCollection_Item(nsframes, index, &nswindow);
356     nsIDOMWindowCollection_Release(nsframes);
357     if(NS_FAILED(nsres)) {
358         FIXME("nsIDOMWindowCollection_Item failed: 0x%08x\n", nsres);
359         return E_FAIL;
360     }
361
362     *ret = nswindow_to_window(nswindow);
363
364     nsIDOMWindow_Release(nswindow);
365     return S_OK;
366 }
367
368 HRESULT get_frame_by_name(HTMLOuterWindow *This, const WCHAR *name, BOOL deep, HTMLOuterWindow **ret)
369 {
370     nsIDOMWindowCollection *nsframes;
371     HTMLOuterWindow *window = NULL;
372     nsIDOMWindow *nswindow;
373     nsAString name_str;
374     UINT32 length, i;
375     nsresult nsres;
376     HRESULT hres = S_OK;
377
378     nsres = nsIDOMWindow_GetFrames(This->nswindow, &nsframes);
379     if(NS_FAILED(nsres)) {
380         FIXME("nsIDOMWindow_GetFrames failed: 0x%08x\n", nsres);
381         return E_FAIL;
382     }
383
384     nsAString_InitDepend(&name_str, name);
385     nsres = nsIDOMWindowCollection_NamedItem(nsframes, &name_str, &nswindow);
386     nsAString_Finish(&name_str);
387     if(NS_FAILED(nsres)) {
388         nsIDOMWindowCollection_Release(nsframes);
389         return E_FAIL;
390     }
391
392     if(nswindow) {
393         *ret = nswindow_to_window(nswindow);
394         return S_OK;
395     }
396
397     nsres = nsIDOMWindowCollection_GetLength(nsframes, &length);
398     assert(nsres == NS_OK);
399
400     for(i = 0; i < length && !window; ++i) {
401         HTMLOuterWindow *window_iter;
402         BSTR id;
403
404         nsres = nsIDOMWindowCollection_Item(nsframes, i, &nswindow);
405         if(NS_FAILED(nsres)) {
406             FIXME("nsIDOMWindowCollection_Item failed: 0x%08x\n", nsres);
407             hres = E_FAIL;
408             break;
409         }
410
411         window_iter = nswindow_to_window(nswindow);
412
413         nsIDOMWindow_Release(nswindow);
414
415         hres = IHTMLElement_get_id(&window_iter->frame_element->element.IHTMLElement_iface, &id);
416         if(FAILED(hres)) {
417             FIXME("IHTMLElement_get_id failed: 0x%08x\n", hres);
418             break;
419         }
420
421         if(id && !strcmpiW(id, name))
422             window = window_iter;
423
424         SysFreeString(id);
425
426         if(!window && deep)
427             get_frame_by_name(window_iter, name, TRUE, &window);
428     }
429
430     nsIDOMWindowCollection_Release(nsframes);
431     if(FAILED(hres))
432         return hres;
433
434     *ret = window;
435     return NS_OK;
436 }
437
438 static HRESULT WINAPI HTMLWindow2_item(IHTMLWindow2 *iface, VARIANT *pvarIndex, VARIANT *pvarResult)
439 {
440     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
441     HTMLOuterWindow *window = NULL;
442     HRESULT hres;
443
444     TRACE("(%p)->(%p %p)\n", This, pvarIndex, pvarResult);
445
446     switch(V_VT(pvarIndex)) {
447     case VT_I4: {
448         int index = V_I4(pvarIndex);
449         TRACE("Getting index %d\n", index);
450         if(index < 0)
451             return DISP_E_MEMBERNOTFOUND;
452         hres = get_frame_by_index(This->outer_window, index, &window);
453         break;
454     }
455     case VT_UINT: {
456         unsigned int index = V_UINT(pvarIndex);
457         TRACE("Getting index %u\n", index);
458         hres = get_frame_by_index(This->outer_window, index, &window);
459         break;
460     }
461     case VT_BSTR: {
462         BSTR str = V_BSTR(pvarIndex);
463         TRACE("Getting name %s\n", wine_dbgstr_w(str));
464         hres = get_frame_by_name(This->outer_window, str, FALSE, &window);
465         break;
466     }
467     default:
468         WARN("Invalid index %s\n", debugstr_variant(pvarIndex));
469         return E_INVALIDARG;
470     }
471
472     if(FAILED(hres))
473         return hres;
474     if(!window)
475         return DISP_E_MEMBERNOTFOUND;
476
477     IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
478     V_VT(pvarResult) = VT_DISPATCH;
479     V_DISPATCH(pvarResult) = (IDispatch*)window;
480     return S_OK;
481 }
482
483 static HRESULT WINAPI HTMLWindow2_get_length(IHTMLWindow2 *iface, LONG *p)
484 {
485     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
486     nsIDOMWindowCollection *nscollection;
487     UINT32 length;
488     nsresult nsres;
489
490     TRACE("(%p)->(%p)\n", This, p);
491
492     nsres = nsIDOMWindow_GetFrames(This->outer_window->nswindow, &nscollection);
493     if(NS_FAILED(nsres)) {
494         ERR("GetFrames failed: %08x\n", nsres);
495         return E_FAIL;
496     }
497
498     nsres = nsIDOMWindowCollection_GetLength(nscollection, &length);
499     nsIDOMWindowCollection_Release(nscollection);
500     if(NS_FAILED(nsres)) {
501         ERR("GetLength failed: %08x\n", nsres);
502         return E_FAIL;
503     }
504
505     *p = length;
506     return S_OK;
507 }
508
509 static HRESULT WINAPI HTMLWindow2_get_frames(IHTMLWindow2 *iface, IHTMLFramesCollection2 **p)
510 {
511     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
512     FIXME("(%p)->(%p): semi-stub\n", This, p);
513
514     /* FIXME: Should return a separate Window object */
515     *p = (IHTMLFramesCollection2*)&This->IHTMLWindow2_iface;
516     HTMLWindow2_AddRef(iface);
517     return S_OK;
518 }
519
520 static HRESULT WINAPI HTMLWindow2_put_defaultStatus(IHTMLWindow2 *iface, BSTR v)
521 {
522     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
523     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
524     return E_NOTIMPL;
525 }
526
527 static HRESULT WINAPI HTMLWindow2_get_defaultStatus(IHTMLWindow2 *iface, BSTR *p)
528 {
529     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
530     FIXME("(%p)->(%p)\n", This, p);
531     return E_NOTIMPL;
532 }
533
534 static HRESULT WINAPI HTMLWindow2_put_status(IHTMLWindow2 *iface, BSTR v)
535 {
536     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
537
538     WARN("(%p)->(%s)\n", This, debugstr_w(v));
539
540     /*
541      * FIXME: Since IE7, setting status is blocked, but still possible in certain circumstances.
542      * Ignoring the call should be enough for us.
543      */
544     return S_OK;
545 }
546
547 static HRESULT WINAPI HTMLWindow2_get_status(IHTMLWindow2 *iface, BSTR *p)
548 {
549     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
550
551     TRACE("(%p)->(%p)\n", This, p);
552
553     /* See put_status */
554     *p = NULL;
555     return S_OK;
556 }
557
558 static HRESULT WINAPI HTMLWindow2_setTimeout(IHTMLWindow2 *iface, BSTR expression,
559         LONG msec, VARIANT *language, LONG *timerID)
560 {
561     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
562     VARIANT expr_var;
563
564     TRACE("(%p)->(%s %d %p %p)\n", This, debugstr_w(expression), msec, language, timerID);
565
566     V_VT(&expr_var) = VT_BSTR;
567     V_BSTR(&expr_var) = expression;
568
569     return IHTMLWindow3_setTimeout(&This->IHTMLWindow3_iface, &expr_var, msec, language, timerID);
570 }
571
572 static HRESULT WINAPI HTMLWindow2_clearTimeout(IHTMLWindow2 *iface, LONG timerID)
573 {
574     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
575
576     TRACE("(%p)->(%d)\n", This, timerID);
577
578     return clear_task_timer(This->inner_window, FALSE, timerID);
579 }
580
581 #define MAX_MESSAGE_LEN 2000
582
583 static HRESULT WINAPI HTMLWindow2_alert(IHTMLWindow2 *iface, BSTR message)
584 {
585     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
586     WCHAR title[100], *msg = message;
587     DWORD len;
588
589     TRACE("(%p)->(%s)\n", This, debugstr_w(message));
590
591     if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, title,
592                     sizeof(title)/sizeof(WCHAR))) {
593         WARN("Could not load message box title: %d\n", GetLastError());
594         return S_OK;
595     }
596
597     len = SysStringLen(message);
598     if(len > MAX_MESSAGE_LEN) {
599         msg = heap_alloc((MAX_MESSAGE_LEN+1)*sizeof(WCHAR));
600         if(!msg)
601             return E_OUTOFMEMORY;
602         memcpy(msg, message, MAX_MESSAGE_LEN*sizeof(WCHAR));
603         msg[MAX_MESSAGE_LEN] = 0;
604     }
605
606     MessageBoxW(This->outer_window->doc_obj->hwnd, msg, title, MB_ICONWARNING);
607     if(msg != message)
608         heap_free(msg);
609     return S_OK;
610 }
611
612 static HRESULT WINAPI HTMLWindow2_confirm(IHTMLWindow2 *iface, BSTR message,
613         VARIANT_BOOL *confirmed)
614 {
615     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
616     WCHAR wszTitle[100];
617
618     TRACE("(%p)->(%s %p)\n", This, debugstr_w(message), confirmed);
619
620     if(!confirmed) return E_INVALIDARG;
621
622     if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle,
623                 sizeof(wszTitle)/sizeof(WCHAR))) {
624         WARN("Could not load message box title: %d\n", GetLastError());
625         *confirmed = VARIANT_TRUE;
626         return S_OK;
627     }
628
629     if(MessageBoxW(This->outer_window->doc_obj->hwnd, message, wszTitle,
630                 MB_OKCANCEL|MB_ICONQUESTION)==IDOK)
631         *confirmed = VARIANT_TRUE;
632     else *confirmed = VARIANT_FALSE;
633
634     return S_OK;
635 }
636
637 typedef struct
638 {
639     BSTR message;
640     BSTR dststr;
641     VARIANT *textdata;
642 }prompt_arg;
643
644 static INT_PTR CALLBACK prompt_dlgproc(HWND hwnd, UINT msg,
645         WPARAM wparam, LPARAM lparam)
646 {
647     switch(msg)
648     {
649         case WM_INITDIALOG:
650         {
651             prompt_arg *arg = (prompt_arg*)lparam;
652             WCHAR wszTitle[100];
653
654             if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle,
655                         sizeof(wszTitle)/sizeof(WCHAR))) {
656                 WARN("Could not load message box title: %d\n", GetLastError());
657                 EndDialog(hwnd, wparam);
658                 return FALSE;
659             }
660
661             SetWindowLongPtrW(hwnd, DWLP_USER, lparam);
662             SetWindowTextW(hwnd, wszTitle);
663             SetWindowTextW(GetDlgItem(hwnd, ID_PROMPT_PROMPT), arg->message);
664             SetWindowTextW(GetDlgItem(hwnd, ID_PROMPT_EDIT), arg->dststr);
665             return FALSE;
666         }
667         case WM_COMMAND:
668             switch(wparam)
669             {
670                 case MAKEWPARAM(IDCANCEL, BN_CLICKED):
671                     EndDialog(hwnd, wparam);
672                     return TRUE;
673                 case MAKEWPARAM(IDOK, BN_CLICKED):
674                 {
675                     prompt_arg *arg =
676                         (prompt_arg*)GetWindowLongPtrW(hwnd, DWLP_USER);
677                     HWND hwndPrompt = GetDlgItem(hwnd, ID_PROMPT_EDIT);
678                     INT len = GetWindowTextLengthW(hwndPrompt);
679
680                     if(!arg->textdata)
681                     {
682                         EndDialog(hwnd, wparam);
683                         return TRUE;
684                     }
685
686                     V_VT(arg->textdata) = VT_BSTR;
687                     if(!len && !arg->dststr)
688                         V_BSTR(arg->textdata) = NULL;
689                     else
690                     {
691                         V_BSTR(arg->textdata) = SysAllocStringLen(NULL, len);
692                         GetWindowTextW(hwndPrompt, V_BSTR(arg->textdata), len+1);
693                     }
694                     EndDialog(hwnd, wparam);
695                     return TRUE;
696                 }
697             }
698             return FALSE;
699         case WM_CLOSE:
700             EndDialog(hwnd, IDCANCEL);
701             return TRUE;
702         default:
703             return FALSE;
704     }
705 }
706
707 static HRESULT WINAPI HTMLWindow2_prompt(IHTMLWindow2 *iface, BSTR message,
708         BSTR dststr, VARIANT *textdata)
709 {
710     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
711     prompt_arg arg;
712
713     TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(message), debugstr_w(dststr), textdata);
714
715     if(textdata) V_VT(textdata) = VT_NULL;
716
717     arg.message = message;
718     arg.dststr = dststr;
719     arg.textdata = textdata;
720
721     DialogBoxParamW(hInst, MAKEINTRESOURCEW(ID_PROMPT_DIALOG),
722             This->outer_window->doc_obj->hwnd, prompt_dlgproc, (LPARAM)&arg);
723     return S_OK;
724 }
725
726 static HRESULT WINAPI HTMLWindow2_get_Image(IHTMLWindow2 *iface, IHTMLImageElementFactory **p)
727 {
728     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
729     HTMLInnerWindow *window = This->inner_window;
730
731     TRACE("(%p)->(%p)\n", This, p);
732
733     if(!window->image_factory) {
734         HRESULT hres;
735
736         hres = HTMLImageElementFactory_Create(window, &window->image_factory);
737         if(FAILED(hres))
738             return hres;
739     }
740
741     *p = &window->image_factory->IHTMLImageElementFactory_iface;
742     IHTMLImageElementFactory_AddRef(*p);
743
744     return S_OK;
745 }
746
747 static HRESULT WINAPI HTMLWindow2_get_location(IHTMLWindow2 *iface, IHTMLLocation **p)
748 {
749     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
750     HTMLLocation *location;
751     HRESULT hres;
752
753     TRACE("(%p)->(%p)\n", This, p);
754
755     hres = get_location(This->inner_window, &location);
756     if(FAILED(hres))
757         return hres;
758
759     *p = &location->IHTMLLocation_iface;
760     return S_OK;
761 }
762
763 static HRESULT WINAPI HTMLWindow2_get_history(IHTMLWindow2 *iface, IOmHistory **p)
764 {
765     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
766     HTMLInnerWindow *window = This->inner_window;
767
768     TRACE("(%p)->(%p)\n", This, p);
769
770     if(!window->history) {
771         HRESULT hres;
772
773         hres = create_history(window, &window->history);
774         if(FAILED(hres))
775             return hres;
776     }
777
778     IOmHistory_AddRef(&window->history->IOmHistory_iface);
779     *p = &window->history->IOmHistory_iface;
780     return S_OK;
781 }
782
783 static BOOL notify_webbrowser_close(HTMLOuterWindow *window, HTMLDocumentObj *doc)
784 {
785     IConnectionPointContainer *cp_container;
786     VARIANT_BOOL cancel = VARIANT_FALSE;
787     IEnumConnections *enum_conn;
788     VARIANT args[2];
789     DISPPARAMS dp = {args, NULL, 2, 0};
790     CONNECTDATA conn_data;
791     IConnectionPoint *cp;
792     IDispatch *disp;
793     ULONG fetched;
794     HRESULT hres;
795
796     if(!doc->webbrowser)
797         return TRUE;
798
799     hres = IUnknown_QueryInterface(doc->webbrowser, &IID_IConnectionPointContainer, (void**)&cp_container);
800     if(FAILED(hres))
801         return TRUE;
802
803     hres = IConnectionPointContainer_FindConnectionPoint(cp_container, &DIID_DWebBrowserEvents2, &cp);
804     IConnectionPointContainer_Release(cp_container);
805     if(FAILED(hres))
806         return TRUE;
807
808     hres = IConnectionPoint_EnumConnections(cp, &enum_conn);
809     IConnectionPoint_Release(cp);
810     if(FAILED(hres))
811         return TRUE;
812
813     while(!cancel) {
814         conn_data.pUnk = NULL;
815         conn_data.dwCookie = 0;
816         fetched = 0;
817         hres = IEnumConnections_Next(enum_conn, 1, &conn_data, &fetched);
818         if(hres != S_OK)
819             break;
820
821         hres = IUnknown_QueryInterface(conn_data.pUnk, &IID_IDispatch, (void**)&disp);
822         IUnknown_Release(conn_data.pUnk);
823         if(FAILED(hres))
824             continue;
825
826         V_VT(args) = VT_BYREF|VT_BOOL;
827         V_BOOLREF(args) = &cancel;
828         V_VT(args+1) = VT_BOOL;
829         V_BOOL(args+1) = window->parent ? VARIANT_TRUE : VARIANT_FALSE;
830         hres = IDispatch_Invoke(disp, DISPID_WINDOWCLOSING, &IID_NULL, 0, DISPATCH_METHOD, &dp, NULL, NULL, NULL);
831         IDispatch_Release(disp);
832         if(FAILED(hres))
833             cancel = VARIANT_FALSE;
834     }
835
836     IEnumConnections_Release(enum_conn);
837     return !cancel;
838 }
839
840 static HRESULT WINAPI HTMLWindow2_close(IHTMLWindow2 *iface)
841 {
842     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
843     HTMLOuterWindow *window = This->outer_window;
844
845     TRACE("(%p)\n", This);
846
847     if(!window->doc_obj) {
848         FIXME("No document object\n");
849         return E_FAIL;
850     }
851
852     if(!notify_webbrowser_close(window, window->doc_obj))
853         return S_OK;
854
855     FIXME("default action not implemented\n");
856     return E_NOTIMPL;
857 }
858
859 static HRESULT WINAPI HTMLWindow2_put_opener(IHTMLWindow2 *iface, VARIANT v)
860 {
861     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
862     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
863     return E_NOTIMPL;
864 }
865
866 static HRESULT WINAPI HTMLWindow2_get_opener(IHTMLWindow2 *iface, VARIANT *p)
867 {
868     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
869
870     FIXME("(%p)->(%p) returning empty\n", This, p);
871
872     V_VT(p) = VT_EMPTY;
873     return S_OK;
874 }
875
876 static HRESULT WINAPI HTMLWindow2_get_navigator(IHTMLWindow2 *iface, IOmNavigator **p)
877 {
878     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
879
880     TRACE("(%p)->(%p)\n", This, p);
881
882     *p = OmNavigator_Create();
883     return *p ? S_OK : E_OUTOFMEMORY;
884 }
885
886 static HRESULT WINAPI HTMLWindow2_put_name(IHTMLWindow2 *iface, BSTR v)
887 {
888     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
889     nsAString name_str;
890     nsresult nsres;
891
892     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
893
894     nsAString_InitDepend(&name_str, v);
895     nsres = nsIDOMWindow_SetName(This->outer_window->nswindow, &name_str);
896     nsAString_Finish(&name_str);
897     if(NS_FAILED(nsres))
898         ERR("SetName failed: %08x\n", nsres);
899
900     return S_OK;
901 }
902
903 static HRESULT WINAPI HTMLWindow2_get_name(IHTMLWindow2 *iface, BSTR *p)
904 {
905     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
906     nsAString name_str;
907     nsresult nsres;
908
909     TRACE("(%p)->(%p)\n", This, p);
910
911     nsAString_Init(&name_str, NULL);
912     nsres = nsIDOMWindow_GetName(This->outer_window->nswindow, &name_str);
913     return return_nsstr(nsres, &name_str, p);
914 }
915
916 static HRESULT WINAPI HTMLWindow2_get_parent(IHTMLWindow2 *iface, IHTMLWindow2 **p)
917 {
918     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
919     HTMLOuterWindow *window = This->outer_window;
920
921     TRACE("(%p)->(%p)\n", This, p);
922
923     if(!window->parent)
924         return IHTMLWindow2_get_self(&This->IHTMLWindow2_iface, p);
925
926     *p = &window->parent->base.IHTMLWindow2_iface;
927     IHTMLWindow2_AddRef(*p);
928     return S_OK;
929 }
930
931 static HRESULT WINAPI HTMLWindow2_open(IHTMLWindow2 *iface, BSTR url, BSTR name,
932          BSTR features, VARIANT_BOOL replace, IHTMLWindow2 **pomWindowResult)
933 {
934     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
935     HTMLOuterWindow *window = This->outer_window;
936     INewWindowManager *new_window_mgr;
937     BSTR uri_str;
938     IUri *uri;
939     HRESULT hres;
940
941     TRACE("(%p)->(%s %s %s %x %p)\n", This, debugstr_w(url), debugstr_w(name),
942           debugstr_w(features), replace, pomWindowResult);
943
944     if(!window->doc_obj || !window->uri_nofrag)
945         return E_UNEXPECTED;
946
947     if(name && *name == '_') {
948         FIXME("Unsupported name %s\n", debugstr_w(name));
949         return E_NOTIMPL;
950     }
951
952     hres = do_query_service((IUnknown*)window->doc_obj->client, &SID_SNewWindowManager, &IID_INewWindowManager,
953             (void**)&new_window_mgr);
954     if(FAILED(hres)) {
955         FIXME("No INewWindowManager\n");
956         return E_NOTIMPL;
957     }
958
959     hres = IUri_GetDisplayUri(window->uri_nofrag, &uri_str);
960     if(SUCCEEDED(hres)) {
961         hres = INewWindowManager_EvaluateNewWindow(new_window_mgr, url, name, uri_str,
962                 features, !!replace, window->doc_obj->has_popup ? 0 : NWMF_FIRST, 0);
963         window->doc_obj->has_popup = TRUE;
964         SysFreeString(uri_str);
965     }
966     INewWindowManager_Release(new_window_mgr);
967     if(FAILED(hres)) {
968         *pomWindowResult = NULL;
969         return S_OK;
970     }
971
972     hres = create_relative_uri(window, url, &uri);
973     if(FAILED(hres))
974         return hres;
975
976     hres = navigate_new_window(window, uri, name, pomWindowResult);
977     IUri_Release(uri);
978     return hres;
979 }
980
981 static HRESULT WINAPI HTMLWindow2_get_self(IHTMLWindow2 *iface, IHTMLWindow2 **p)
982 {
983     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
984
985     TRACE("(%p)->(%p)\n", This, p);
986
987     /* FIXME: We should return kind of proxy window here. */
988     IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
989     *p = &This->IHTMLWindow2_iface;
990     return S_OK;
991 }
992
993 static HRESULT WINAPI HTMLWindow2_get_top(IHTMLWindow2 *iface, IHTMLWindow2 **p)
994 {
995     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
996     HTMLOuterWindow *top;
997
998     TRACE("(%p)->(%p)\n", This, p);
999
1000     get_top_window(This->outer_window, &top);
1001     *p = &top->base.IHTMLWindow2_iface;
1002     IHTMLWindow2_AddRef(*p);
1003
1004     return S_OK;
1005 }
1006
1007 static HRESULT WINAPI HTMLWindow2_get_window(IHTMLWindow2 *iface, IHTMLWindow2 **p)
1008 {
1009     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1010
1011     TRACE("(%p)->(%p)\n", This, p);
1012
1013     /* FIXME: We should return kind of proxy window here. */
1014     IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
1015     *p = &This->IHTMLWindow2_iface;
1016     return S_OK;
1017 }
1018
1019 static HRESULT WINAPI HTMLWindow2_navigate(IHTMLWindow2 *iface, BSTR url)
1020 {
1021     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1022     FIXME("(%p)->(%s)\n", This, debugstr_w(url));
1023     return E_NOTIMPL;
1024 }
1025
1026 static HRESULT WINAPI HTMLWindow2_put_onfocus(IHTMLWindow2 *iface, VARIANT v)
1027 {
1028     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1029
1030     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1031
1032     return set_window_event(This, EVENTID_FOCUS, &v);
1033 }
1034
1035 static HRESULT WINAPI HTMLWindow2_get_onfocus(IHTMLWindow2 *iface, VARIANT *p)
1036 {
1037     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1038
1039     TRACE("(%p)->(%p)\n", This, p);
1040
1041     return get_window_event(This, EVENTID_FOCUS, p);
1042 }
1043
1044 static HRESULT WINAPI HTMLWindow2_put_onblur(IHTMLWindow2 *iface, VARIANT v)
1045 {
1046     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1047
1048     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1049
1050     return set_window_event(This, EVENTID_BLUR, &v);
1051 }
1052
1053 static HRESULT WINAPI HTMLWindow2_get_onblur(IHTMLWindow2 *iface, VARIANT *p)
1054 {
1055     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1056
1057     TRACE("(%p)->(%p)\n", This, p);
1058
1059     return get_window_event(This, EVENTID_BLUR, p);
1060 }
1061
1062 static HRESULT WINAPI HTMLWindow2_put_onload(IHTMLWindow2 *iface, VARIANT v)
1063 {
1064     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1065
1066     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1067
1068     return set_window_event(This, EVENTID_LOAD, &v);
1069 }
1070
1071 static HRESULT WINAPI HTMLWindow2_get_onload(IHTMLWindow2 *iface, VARIANT *p)
1072 {
1073     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1074
1075     TRACE("(%p)->(%p)\n", This, p);
1076
1077     return get_window_event(This, EVENTID_LOAD, p);
1078 }
1079
1080 static HRESULT WINAPI HTMLWindow2_put_onbeforeunload(IHTMLWindow2 *iface, VARIANT v)
1081 {
1082     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1083
1084     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1085
1086     return set_window_event(This, EVENTID_BEFOREUNLOAD, &v);
1087 }
1088
1089 static HRESULT WINAPI HTMLWindow2_get_onbeforeunload(IHTMLWindow2 *iface, VARIANT *p)
1090 {
1091     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1092
1093     TRACE("(%p)->(%p)\n", This, p);
1094
1095     return get_window_event(This, EVENTID_BEFOREUNLOAD, p);
1096 }
1097
1098 static HRESULT WINAPI HTMLWindow2_put_onunload(IHTMLWindow2 *iface, VARIANT v)
1099 {
1100     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1101     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1102     return E_NOTIMPL;
1103 }
1104
1105 static HRESULT WINAPI HTMLWindow2_get_onunload(IHTMLWindow2 *iface, VARIANT *p)
1106 {
1107     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1108     FIXME("(%p)->(%p)\n", This, p);
1109     return E_NOTIMPL;
1110 }
1111
1112 static HRESULT WINAPI HTMLWindow2_put_onhelp(IHTMLWindow2 *iface, VARIANT v)
1113 {
1114     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1115
1116     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1117
1118     return set_window_event(This, EVENTID_HELP, &v);
1119 }
1120
1121 static HRESULT WINAPI HTMLWindow2_get_onhelp(IHTMLWindow2 *iface, VARIANT *p)
1122 {
1123     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1124
1125     TRACE("(%p)->(%p)\n", This, p);
1126
1127     return get_window_event(This, EVENTID_HELP, p);
1128 }
1129
1130 static HRESULT WINAPI HTMLWindow2_put_onerror(IHTMLWindow2 *iface, VARIANT v)
1131 {
1132     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1133
1134     FIXME("(%p)->(%s) semi-stub\n", This, debugstr_variant(&v));
1135
1136     return set_window_event(This, EVENTID_ERROR, &v);
1137 }
1138
1139 static HRESULT WINAPI HTMLWindow2_get_onerror(IHTMLWindow2 *iface, VARIANT *p)
1140 {
1141     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1142
1143     TRACE("(%p)->(%p)\n", This, p);
1144
1145     return get_window_event(This, EVENTID_ERROR, p);
1146 }
1147
1148 static HRESULT WINAPI HTMLWindow2_put_onresize(IHTMLWindow2 *iface, VARIANT v)
1149 {
1150     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1151
1152     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1153
1154     return set_window_event(This, EVENTID_RESIZE, &v);
1155 }
1156
1157 static HRESULT WINAPI HTMLWindow2_get_onresize(IHTMLWindow2 *iface, VARIANT *p)
1158 {
1159     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1160
1161     TRACE("(%p)->(%p)\n", This, p);
1162
1163     return get_window_event(This, EVENTID_RESIZE, p);
1164 }
1165
1166 static HRESULT WINAPI HTMLWindow2_put_onscroll(IHTMLWindow2 *iface, VARIANT v)
1167 {
1168     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1169
1170     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1171
1172     return set_window_event(This, EVENTID_SCROLL, &v);
1173 }
1174
1175 static HRESULT WINAPI HTMLWindow2_get_onscroll(IHTMLWindow2 *iface, VARIANT *p)
1176 {
1177     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1178
1179     TRACE("(%p)->(%p)\n", This, p);
1180
1181     return get_window_event(This, EVENTID_SCROLL, p);
1182 }
1183
1184 static HRESULT WINAPI HTMLWindow2_get_document(IHTMLWindow2 *iface, IHTMLDocument2 **p)
1185 {
1186     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1187
1188     TRACE("(%p)->(%p)\n", This, p);
1189
1190     if(This->inner_window->doc) {
1191         /* FIXME: We should return a wrapper object here */
1192         *p = &This->inner_window->doc->basedoc.IHTMLDocument2_iface;
1193         IHTMLDocument2_AddRef(*p);
1194     }else {
1195         *p = NULL;
1196     }
1197
1198     return S_OK;
1199 }
1200
1201 static HRESULT WINAPI HTMLWindow2_get_event(IHTMLWindow2 *iface, IHTMLEventObj **p)
1202 {
1203     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1204     HTMLInnerWindow *window = This->inner_window;
1205
1206     TRACE("(%p)->(%p)\n", This, p);
1207
1208     if(window->event)
1209         IHTMLEventObj_AddRef(window->event);
1210     *p = window->event;
1211     return S_OK;
1212 }
1213
1214 static HRESULT WINAPI HTMLWindow2_get__newEnum(IHTMLWindow2 *iface, IUnknown **p)
1215 {
1216     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1217     FIXME("(%p)->(%p)\n", This, p);
1218     return E_NOTIMPL;
1219 }
1220
1221 static HRESULT WINAPI HTMLWindow2_showModalDialog(IHTMLWindow2 *iface, BSTR dialog,
1222         VARIANT *varArgIn, VARIANT *varOptions, VARIANT *varArgOut)
1223 {
1224     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1225     FIXME("(%p)->(%s %p %p %p)\n", This, debugstr_w(dialog), varArgIn, varOptions, varArgOut);
1226     return E_NOTIMPL;
1227 }
1228
1229 static HRESULT WINAPI HTMLWindow2_showHelp(IHTMLWindow2 *iface, BSTR helpURL, VARIANT helpArg,
1230         BSTR features)
1231 {
1232     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1233     FIXME("(%p)->(%s %s %s)\n", This, debugstr_w(helpURL), debugstr_variant(&helpArg), debugstr_w(features));
1234     return E_NOTIMPL;
1235 }
1236
1237 static HRESULT WINAPI HTMLWindow2_get_screen(IHTMLWindow2 *iface, IHTMLScreen **p)
1238 {
1239     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1240     HTMLInnerWindow *window = This->inner_window;
1241
1242     TRACE("(%p)->(%p)\n", This, p);
1243
1244     if(!window->screen) {
1245         HRESULT hres;
1246
1247         hres = HTMLScreen_Create(&window->screen);
1248         if(FAILED(hres))
1249             return hres;
1250     }
1251
1252     *p = window->screen;
1253     IHTMLScreen_AddRef(window->screen);
1254     return S_OK;
1255 }
1256
1257 static HRESULT WINAPI HTMLWindow2_get_Option(IHTMLWindow2 *iface, IHTMLOptionElementFactory **p)
1258 {
1259     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1260     HTMLInnerWindow *window = This->inner_window;
1261
1262     TRACE("(%p)->(%p)\n", This, p);
1263
1264     if(!window->option_factory) {
1265         HRESULT hres;
1266
1267         hres = HTMLOptionElementFactory_Create(window, &window->option_factory);
1268         if(FAILED(hres))
1269             return hres;
1270     }
1271
1272     *p = &window->option_factory->IHTMLOptionElementFactory_iface;
1273     IHTMLOptionElementFactory_AddRef(*p);
1274
1275     return S_OK;
1276 }
1277
1278 static HRESULT WINAPI HTMLWindow2_focus(IHTMLWindow2 *iface)
1279 {
1280     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1281
1282     TRACE("(%p)->()\n", This);
1283
1284     if(This->outer_window->doc_obj)
1285         SetFocus(This->outer_window->doc_obj->hwnd);
1286     return S_OK;
1287 }
1288
1289 static HRESULT WINAPI HTMLWindow2_get_closed(IHTMLWindow2 *iface, VARIANT_BOOL *p)
1290 {
1291     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1292     FIXME("(%p)->(%p)\n", This, p);
1293     return E_NOTIMPL;
1294 }
1295
1296 static HRESULT WINAPI HTMLWindow2_blur(IHTMLWindow2 *iface)
1297 {
1298     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1299     FIXME("(%p)->()\n", This);
1300     return E_NOTIMPL;
1301 }
1302
1303 static HRESULT WINAPI HTMLWindow2_scroll(IHTMLWindow2 *iface, LONG x, LONG y)
1304 {
1305     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1306     FIXME("(%p)->(%d %d)\n", This, x, y);
1307     return E_NOTIMPL;
1308 }
1309
1310 static HRESULT WINAPI HTMLWindow2_get_clientInformation(IHTMLWindow2 *iface, IOmNavigator **p)
1311 {
1312     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1313     FIXME("(%p)->(%p)\n", This, p);
1314     return E_NOTIMPL;
1315 }
1316
1317 static HRESULT WINAPI HTMLWindow2_setInterval(IHTMLWindow2 *iface, BSTR expression,
1318         LONG msec, VARIANT *language, LONG *timerID)
1319 {
1320     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1321     VARIANT expr;
1322
1323     TRACE("(%p)->(%s %d %p %p)\n", This, debugstr_w(expression), msec, language, timerID);
1324
1325     V_VT(&expr) = VT_BSTR;
1326     V_BSTR(&expr) = expression;
1327     return IHTMLWindow3_setInterval(&This->IHTMLWindow3_iface, &expr, msec, language, timerID);
1328 }
1329
1330 static HRESULT WINAPI HTMLWindow2_clearInterval(IHTMLWindow2 *iface, LONG timerID)
1331 {
1332     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1333
1334     TRACE("(%p)->(%d)\n", This, timerID);
1335
1336     return clear_task_timer(This->inner_window, TRUE, timerID);
1337 }
1338
1339 static HRESULT WINAPI HTMLWindow2_put_offscreenBuffering(IHTMLWindow2 *iface, VARIANT v)
1340 {
1341     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1342     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1343     return E_NOTIMPL;
1344 }
1345
1346 static HRESULT WINAPI HTMLWindow2_get_offscreenBuffering(IHTMLWindow2 *iface, VARIANT *p)
1347 {
1348     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1349     FIXME("(%p)->(%p)\n", This, p);
1350     return E_NOTIMPL;
1351 }
1352
1353 static HRESULT WINAPI HTMLWindow2_execScript(IHTMLWindow2 *iface, BSTR scode, BSTR language,
1354         VARIANT *pvarRet)
1355 {
1356     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1357
1358     TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(scode), debugstr_w(language), pvarRet);
1359
1360     return exec_script(This->inner_window, scode, language, pvarRet);
1361 }
1362
1363 static HRESULT WINAPI HTMLWindow2_toString(IHTMLWindow2 *iface, BSTR *String)
1364 {
1365     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1366
1367     static const WCHAR objectW[] = {'[','o','b','j','e','c','t',']',0};
1368
1369     TRACE("(%p)->(%p)\n", This, String);
1370
1371     if(!String)
1372         return E_INVALIDARG;
1373
1374     *String = SysAllocString(objectW);
1375     return *String ? S_OK : E_OUTOFMEMORY;
1376 }
1377
1378 static HRESULT WINAPI HTMLWindow2_scrollBy(IHTMLWindow2 *iface, LONG x, LONG y)
1379 {
1380     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1381     nsresult nsres;
1382
1383     TRACE("(%p)->(%d %d)\n", This, x, y);
1384
1385     nsres = nsIDOMWindow_ScrollBy(This->outer_window->nswindow, x, y);
1386     if(NS_FAILED(nsres))
1387         ERR("ScrollBy failed: %08x\n", nsres);
1388
1389     return S_OK;
1390 }
1391
1392 static HRESULT WINAPI HTMLWindow2_scrollTo(IHTMLWindow2 *iface, LONG x, LONG y)
1393 {
1394     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1395     nsresult nsres;
1396
1397     TRACE("(%p)->(%d %d)\n", This, x, y);
1398
1399     nsres = nsIDOMWindow_ScrollTo(This->outer_window->nswindow, x, y);
1400     if(NS_FAILED(nsres))
1401         ERR("ScrollTo failed: %08x\n", nsres);
1402
1403     return S_OK;
1404 }
1405
1406 static HRESULT WINAPI HTMLWindow2_moveTo(IHTMLWindow2 *iface, LONG x, LONG y)
1407 {
1408     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1409     FIXME("(%p)->(%d %d)\n", This, x, y);
1410     return E_NOTIMPL;
1411 }
1412
1413 static HRESULT WINAPI HTMLWindow2_moveBy(IHTMLWindow2 *iface, LONG x, LONG y)
1414 {
1415     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1416     FIXME("(%p)->(%d %d)\n", This, x, y);
1417     return E_NOTIMPL;
1418 }
1419
1420 static HRESULT WINAPI HTMLWindow2_resizeTo(IHTMLWindow2 *iface, LONG x, LONG y)
1421 {
1422     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1423     FIXME("(%p)->(%d %d)\n", This, x, y);
1424     return E_NOTIMPL;
1425 }
1426
1427 static HRESULT WINAPI HTMLWindow2_resizeBy(IHTMLWindow2 *iface, LONG x, LONG y)
1428 {
1429     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1430     FIXME("(%p)->(%d %d)\n", This, x, y);
1431     return E_NOTIMPL;
1432 }
1433
1434 static HRESULT WINAPI HTMLWindow2_get_external(IHTMLWindow2 *iface, IDispatch **p)
1435 {
1436     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1437
1438     TRACE("(%p)->(%p)\n", This, p);
1439
1440     *p = NULL;
1441
1442     if(!This->outer_window->doc_obj->hostui)
1443         return S_OK;
1444
1445     return IDocHostUIHandler_GetExternal(This->outer_window->doc_obj->hostui, p);
1446 }
1447
1448 static const IHTMLWindow2Vtbl HTMLWindow2Vtbl = {
1449     HTMLWindow2_QueryInterface,
1450     HTMLWindow2_AddRef,
1451     HTMLWindow2_Release,
1452     HTMLWindow2_GetTypeInfoCount,
1453     HTMLWindow2_GetTypeInfo,
1454     HTMLWindow2_GetIDsOfNames,
1455     HTMLWindow2_Invoke,
1456     HTMLWindow2_item,
1457     HTMLWindow2_get_length,
1458     HTMLWindow2_get_frames,
1459     HTMLWindow2_put_defaultStatus,
1460     HTMLWindow2_get_defaultStatus,
1461     HTMLWindow2_put_status,
1462     HTMLWindow2_get_status,
1463     HTMLWindow2_setTimeout,
1464     HTMLWindow2_clearTimeout,
1465     HTMLWindow2_alert,
1466     HTMLWindow2_confirm,
1467     HTMLWindow2_prompt,
1468     HTMLWindow2_get_Image,
1469     HTMLWindow2_get_location,
1470     HTMLWindow2_get_history,
1471     HTMLWindow2_close,
1472     HTMLWindow2_put_opener,
1473     HTMLWindow2_get_opener,
1474     HTMLWindow2_get_navigator,
1475     HTMLWindow2_put_name,
1476     HTMLWindow2_get_name,
1477     HTMLWindow2_get_parent,
1478     HTMLWindow2_open,
1479     HTMLWindow2_get_self,
1480     HTMLWindow2_get_top,
1481     HTMLWindow2_get_window,
1482     HTMLWindow2_navigate,
1483     HTMLWindow2_put_onfocus,
1484     HTMLWindow2_get_onfocus,
1485     HTMLWindow2_put_onblur,
1486     HTMLWindow2_get_onblur,
1487     HTMLWindow2_put_onload,
1488     HTMLWindow2_get_onload,
1489     HTMLWindow2_put_onbeforeunload,
1490     HTMLWindow2_get_onbeforeunload,
1491     HTMLWindow2_put_onunload,
1492     HTMLWindow2_get_onunload,
1493     HTMLWindow2_put_onhelp,
1494     HTMLWindow2_get_onhelp,
1495     HTMLWindow2_put_onerror,
1496     HTMLWindow2_get_onerror,
1497     HTMLWindow2_put_onresize,
1498     HTMLWindow2_get_onresize,
1499     HTMLWindow2_put_onscroll,
1500     HTMLWindow2_get_onscroll,
1501     HTMLWindow2_get_document,
1502     HTMLWindow2_get_event,
1503     HTMLWindow2_get__newEnum,
1504     HTMLWindow2_showModalDialog,
1505     HTMLWindow2_showHelp,
1506     HTMLWindow2_get_screen,
1507     HTMLWindow2_get_Option,
1508     HTMLWindow2_focus,
1509     HTMLWindow2_get_closed,
1510     HTMLWindow2_blur,
1511     HTMLWindow2_scroll,
1512     HTMLWindow2_get_clientInformation,
1513     HTMLWindow2_setInterval,
1514     HTMLWindow2_clearInterval,
1515     HTMLWindow2_put_offscreenBuffering,
1516     HTMLWindow2_get_offscreenBuffering,
1517     HTMLWindow2_execScript,
1518     HTMLWindow2_toString,
1519     HTMLWindow2_scrollBy,
1520     HTMLWindow2_scrollTo,
1521     HTMLWindow2_moveTo,
1522     HTMLWindow2_moveBy,
1523     HTMLWindow2_resizeTo,
1524     HTMLWindow2_resizeBy,
1525     HTMLWindow2_get_external
1526 };
1527
1528 static inline HTMLWindow *impl_from_IHTMLWindow3(IHTMLWindow3 *iface)
1529 {
1530     return CONTAINING_RECORD(iface, HTMLWindow, IHTMLWindow3_iface);
1531 }
1532
1533 static HRESULT WINAPI HTMLWindow3_QueryInterface(IHTMLWindow3 *iface, REFIID riid, void **ppv)
1534 {
1535     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1536
1537     return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
1538 }
1539
1540 static ULONG WINAPI HTMLWindow3_AddRef(IHTMLWindow3 *iface)
1541 {
1542     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1543
1544     return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
1545 }
1546
1547 static ULONG WINAPI HTMLWindow3_Release(IHTMLWindow3 *iface)
1548 {
1549     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1550
1551     return IHTMLWindow2_Release(&This->IHTMLWindow2_iface);
1552 }
1553
1554 static HRESULT WINAPI HTMLWindow3_GetTypeInfoCount(IHTMLWindow3 *iface, UINT *pctinfo)
1555 {
1556     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1557
1558     return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo);
1559 }
1560
1561 static HRESULT WINAPI HTMLWindow3_GetTypeInfo(IHTMLWindow3 *iface, UINT iTInfo,
1562                                               LCID lcid, ITypeInfo **ppTInfo)
1563 {
1564     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1565
1566     return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo);
1567 }
1568
1569 static HRESULT WINAPI HTMLWindow3_GetIDsOfNames(IHTMLWindow3 *iface, REFIID riid,
1570                                                 LPOLESTR *rgszNames, UINT cNames,
1571                                                 LCID lcid, DISPID *rgDispId)
1572 {
1573     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1574
1575     return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid,
1576             rgDispId);
1577 }
1578
1579 static HRESULT WINAPI HTMLWindow3_Invoke(IHTMLWindow3 *iface, DISPID dispIdMember,
1580                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1581                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1582 {
1583     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1584
1585     return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
1586             pDispParams, pVarResult, pExcepInfo, puArgErr);
1587 }
1588
1589 static HRESULT WINAPI HTMLWindow3_get_screenLeft(IHTMLWindow3 *iface, LONG *p)
1590 {
1591     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1592     FIXME("(%p)->(%p)\n", This, p);
1593     return E_NOTIMPL;
1594 }
1595
1596 static HRESULT WINAPI HTMLWindow3_get_screenTop(IHTMLWindow3 *iface, LONG *p)
1597 {
1598     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1599     FIXME("(%p)->(%p)\n", This, p);
1600     return E_NOTIMPL;
1601 }
1602
1603 static HRESULT WINAPI HTMLWindow3_attachEvent(IHTMLWindow3 *iface, BSTR event, IDispatch *pDisp, VARIANT_BOOL *pfResult)
1604 {
1605     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1606     HTMLInnerWindow *window = This->inner_window;
1607
1608     TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(event), pDisp, pfResult);
1609
1610     if(!window->doc) {
1611         FIXME("No document\n");
1612         return E_FAIL;
1613     }
1614
1615     return attach_event(&window->doc->body_event_target, NULL, &window->doc->basedoc, event, pDisp, pfResult);
1616 }
1617
1618 static HRESULT WINAPI HTMLWindow3_detachEvent(IHTMLWindow3 *iface, BSTR event, IDispatch *pDisp)
1619 {
1620     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1621     HTMLInnerWindow *window = This->inner_window;
1622
1623     TRACE("(%p)->()\n", This);
1624
1625     if(!window->doc) {
1626         FIXME("No document\n");
1627         return E_FAIL;
1628     }
1629
1630     return detach_event(window->doc->body_event_target, &window->doc->basedoc, event, pDisp);
1631 }
1632
1633 static HRESULT window_set_timer(HTMLInnerWindow *This, VARIANT *expr, LONG msec, VARIANT *language,
1634         BOOL interval, LONG *timer_id)
1635 {
1636     IDispatch *disp = NULL;
1637     HRESULT hres;
1638
1639     switch(V_VT(expr)) {
1640     case VT_DISPATCH:
1641         disp = V_DISPATCH(expr);
1642         IDispatch_AddRef(disp);
1643         break;
1644
1645     case VT_BSTR:
1646         disp = script_parse_event(This->base.inner_window, V_BSTR(expr));
1647         break;
1648
1649     default:
1650         FIXME("unimplemented expr %s\n", debugstr_variant(expr));
1651         return E_NOTIMPL;
1652     }
1653
1654     if(!disp)
1655         return E_FAIL;
1656
1657     hres = set_task_timer(This, msec, interval, disp, timer_id);
1658     IDispatch_Release(disp);
1659
1660     return hres;
1661 }
1662
1663 static HRESULT WINAPI HTMLWindow3_setTimeout(IHTMLWindow3 *iface, VARIANT *expression, LONG msec,
1664         VARIANT *language, LONG *timerID)
1665 {
1666     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1667
1668     TRACE("(%p)->(%s %d %s %p)\n", This, debugstr_variant(expression), msec, debugstr_variant(language), timerID);
1669
1670     return window_set_timer(This->inner_window, expression, msec, language, FALSE, timerID);
1671 }
1672
1673 static HRESULT WINAPI HTMLWindow3_setInterval(IHTMLWindow3 *iface, VARIANT *expression, LONG msec,
1674         VARIANT *language, LONG *timerID)
1675 {
1676     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1677
1678     TRACE("(%p)->(%p %d %p %p)\n", This, expression, msec, language, timerID);
1679
1680     return window_set_timer(This->inner_window, expression, msec, language, TRUE, timerID);
1681 }
1682
1683 static HRESULT WINAPI HTMLWindow3_print(IHTMLWindow3 *iface)
1684 {
1685     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1686     FIXME("(%p)\n", This);
1687     return E_NOTIMPL;
1688 }
1689
1690 static HRESULT WINAPI HTMLWindow3_put_onbeforeprint(IHTMLWindow3 *iface, VARIANT v)
1691 {
1692     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1693     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1694     return E_NOTIMPL;
1695 }
1696
1697 static HRESULT WINAPI HTMLWindow3_get_onbeforeprint(IHTMLWindow3 *iface, VARIANT *p)
1698 {
1699     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1700     FIXME("(%p)->(%p)\n", This, p);
1701     return E_NOTIMPL;
1702 }
1703
1704 static HRESULT WINAPI HTMLWindow3_put_onafterprint(IHTMLWindow3 *iface, VARIANT v)
1705 {
1706     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1707     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1708     return E_NOTIMPL;
1709 }
1710
1711 static HRESULT WINAPI HTMLWindow3_get_onafterprint(IHTMLWindow3 *iface, VARIANT *p)
1712 {
1713     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1714     FIXME("(%p)->(%p)\n", This, p);
1715     return E_NOTIMPL;
1716 }
1717
1718 static HRESULT WINAPI HTMLWindow3_get_clipboardData(IHTMLWindow3 *iface, IHTMLDataTransfer **p)
1719 {
1720     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1721     FIXME("(%p)->(%p)\n", This, p);
1722     return E_NOTIMPL;
1723 }
1724
1725 static HRESULT WINAPI HTMLWindow3_showModelessDialog(IHTMLWindow3 *iface, BSTR url,
1726         VARIANT *varArgIn, VARIANT *options, IHTMLWindow2 **pDialog)
1727 {
1728     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1729     FIXME("(%p)->(%s %p %p %p)\n", This, debugstr_w(url), varArgIn, options, pDialog);
1730     return E_NOTIMPL;
1731 }
1732
1733 static const IHTMLWindow3Vtbl HTMLWindow3Vtbl = {
1734     HTMLWindow3_QueryInterface,
1735     HTMLWindow3_AddRef,
1736     HTMLWindow3_Release,
1737     HTMLWindow3_GetTypeInfoCount,
1738     HTMLWindow3_GetTypeInfo,
1739     HTMLWindow3_GetIDsOfNames,
1740     HTMLWindow3_Invoke,
1741     HTMLWindow3_get_screenLeft,
1742     HTMLWindow3_get_screenTop,
1743     HTMLWindow3_attachEvent,
1744     HTMLWindow3_detachEvent,
1745     HTMLWindow3_setTimeout,
1746     HTMLWindow3_setInterval,
1747     HTMLWindow3_print,
1748     HTMLWindow3_put_onbeforeprint,
1749     HTMLWindow3_get_onbeforeprint,
1750     HTMLWindow3_put_onafterprint,
1751     HTMLWindow3_get_onafterprint,
1752     HTMLWindow3_get_clipboardData,
1753     HTMLWindow3_showModelessDialog
1754 };
1755
1756 static inline HTMLWindow *impl_from_IHTMLWindow4(IHTMLWindow4 *iface)
1757 {
1758     return CONTAINING_RECORD(iface, HTMLWindow, IHTMLWindow4_iface);
1759 }
1760
1761 static HRESULT WINAPI HTMLWindow4_QueryInterface(IHTMLWindow4 *iface, REFIID riid, void **ppv)
1762 {
1763     HTMLWindow *This = impl_from_IHTMLWindow4(iface);
1764
1765     return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
1766 }
1767
1768 static ULONG WINAPI HTMLWindow4_AddRef(IHTMLWindow4 *iface)
1769 {
1770     HTMLWindow *This = impl_from_IHTMLWindow4(iface);
1771
1772     return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
1773 }
1774
1775 static ULONG WINAPI HTMLWindow4_Release(IHTMLWindow4 *iface)
1776 {
1777     HTMLWindow *This = impl_from_IHTMLWindow4(iface);
1778
1779     return IHTMLWindow2_Release(&This->IHTMLWindow2_iface);
1780 }
1781
1782 static HRESULT WINAPI HTMLWindow4_GetTypeInfoCount(IHTMLWindow4 *iface, UINT *pctinfo)
1783 {
1784     HTMLWindow *This = impl_from_IHTMLWindow4(iface);
1785
1786     return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo);
1787 }
1788
1789 static HRESULT WINAPI HTMLWindow4_GetTypeInfo(IHTMLWindow4 *iface, UINT iTInfo,
1790                                               LCID lcid, ITypeInfo **ppTInfo)
1791 {
1792     HTMLWindow *This = impl_from_IHTMLWindow4(iface);
1793
1794     return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo);
1795 }
1796
1797 static HRESULT WINAPI HTMLWindow4_GetIDsOfNames(IHTMLWindow4 *iface, REFIID riid,
1798                                                 LPOLESTR *rgszNames, UINT cNames,
1799                                                 LCID lcid, DISPID *rgDispId)
1800 {
1801     HTMLWindow *This = impl_from_IHTMLWindow4(iface);
1802
1803     return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid,
1804             rgDispId);
1805 }
1806
1807 static HRESULT WINAPI HTMLWindow4_Invoke(IHTMLWindow4 *iface, DISPID dispIdMember,
1808                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1809                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1810 {
1811     HTMLWindow *This = impl_from_IHTMLWindow4(iface);
1812
1813     return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
1814             pDispParams, pVarResult, pExcepInfo, puArgErr);
1815 }
1816
1817 static HRESULT WINAPI HTMLWindow4_createPopup(IHTMLWindow4 *iface, VARIANT *varArgIn,
1818                             IDispatch **ppPopup)
1819 {
1820     HTMLWindow *This = impl_from_IHTMLWindow4(iface);
1821     FIXME("(%p)->(%p %p)\n", This, varArgIn, ppPopup);
1822     return E_NOTIMPL;
1823 }
1824
1825 static HRESULT WINAPI HTMLWindow4_get_frameElement(IHTMLWindow4 *iface, IHTMLFrameBase **p)
1826 {
1827     HTMLWindow *This = impl_from_IHTMLWindow4(iface);
1828     TRACE("(%p)->(%p)\n", This, p);
1829
1830     if(This->outer_window->frame_element) {
1831         *p = &This->outer_window->frame_element->IHTMLFrameBase_iface;
1832         IHTMLFrameBase_AddRef(*p);
1833     }else
1834         *p = NULL;
1835
1836     return S_OK;
1837 }
1838
1839 static const IHTMLWindow4Vtbl HTMLWindow4Vtbl = {
1840     HTMLWindow4_QueryInterface,
1841     HTMLWindow4_AddRef,
1842     HTMLWindow4_Release,
1843     HTMLWindow4_GetTypeInfoCount,
1844     HTMLWindow4_GetTypeInfo,
1845     HTMLWindow4_GetIDsOfNames,
1846     HTMLWindow4_Invoke,
1847     HTMLWindow4_createPopup,
1848     HTMLWindow4_get_frameElement
1849 };
1850
1851 static inline HTMLWindow *impl_from_IHTMLWindow5(IHTMLWindow5 *iface)
1852 {
1853     return CONTAINING_RECORD(iface, HTMLWindow, IHTMLWindow5_iface);
1854 }
1855
1856 static HRESULT WINAPI HTMLWindow5_QueryInterface(IHTMLWindow5 *iface, REFIID riid, void **ppv)
1857 {
1858     HTMLWindow *This = impl_from_IHTMLWindow5(iface);
1859
1860     return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
1861 }
1862
1863 static ULONG WINAPI HTMLWindow5_AddRef(IHTMLWindow5 *iface)
1864 {
1865     HTMLWindow *This = impl_from_IHTMLWindow5(iface);
1866
1867     return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
1868 }
1869
1870 static ULONG WINAPI HTMLWindow5_Release(IHTMLWindow5 *iface)
1871 {
1872     HTMLWindow *This = impl_from_IHTMLWindow5(iface);
1873
1874     return IHTMLWindow2_Release(&This->IHTMLWindow2_iface);
1875 }
1876
1877 static HRESULT WINAPI HTMLWindow5_GetTypeInfoCount(IHTMLWindow5 *iface, UINT *pctinfo)
1878 {
1879     HTMLWindow *This = impl_from_IHTMLWindow5(iface);
1880
1881     return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo);
1882 }
1883
1884 static HRESULT WINAPI HTMLWindow5_GetTypeInfo(IHTMLWindow5 *iface, UINT iTInfo,
1885         LCID lcid, ITypeInfo **ppTInfo)
1886 {
1887     HTMLWindow *This = impl_from_IHTMLWindow5(iface);
1888
1889     return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo);
1890 }
1891
1892 static HRESULT WINAPI HTMLWindow5_GetIDsOfNames(IHTMLWindow5 *iface, REFIID riid,
1893         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1894 {
1895     HTMLWindow *This = impl_from_IHTMLWindow5(iface);
1896
1897     return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid,
1898             rgDispId);
1899 }
1900
1901 static HRESULT WINAPI HTMLWindow5_Invoke(IHTMLWindow5 *iface, DISPID dispIdMember,
1902         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1903         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1904 {
1905     HTMLWindow *This = impl_from_IHTMLWindow5(iface);
1906
1907     return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
1908             pDispParams, pVarResult, pExcepInfo, puArgErr);
1909 }
1910
1911 static HRESULT WINAPI HTMLWindow5_put_XMLHttpRequest(IHTMLWindow5 *iface, VARIANT v)
1912 {
1913     HTMLWindow *This = impl_from_IHTMLWindow5(iface);
1914     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1915     return E_NOTIMPL;
1916 }
1917
1918 static HRESULT WINAPI HTMLWindow5_get_XMLHttpRequest(IHTMLWindow5 *iface, VARIANT *p)
1919 {
1920     HTMLWindow *This = impl_from_IHTMLWindow5(iface);
1921     FIXME("(%p)->(%p)\n", This, p);
1922     return E_NOTIMPL;
1923 }
1924
1925 static const IHTMLWindow5Vtbl HTMLWindow5Vtbl = {
1926     HTMLWindow5_QueryInterface,
1927     HTMLWindow5_AddRef,
1928     HTMLWindow5_Release,
1929     HTMLWindow5_GetTypeInfoCount,
1930     HTMLWindow5_GetTypeInfo,
1931     HTMLWindow5_GetIDsOfNames,
1932     HTMLWindow5_Invoke,
1933     HTMLWindow5_put_XMLHttpRequest,
1934     HTMLWindow5_get_XMLHttpRequest
1935 };
1936
1937 static inline HTMLWindow *impl_from_IHTMLWindow6(IHTMLWindow6 *iface)
1938 {
1939     return CONTAINING_RECORD(iface, HTMLWindow, IHTMLWindow6_iface);
1940 }
1941
1942 static HRESULT WINAPI HTMLWindow6_QueryInterface(IHTMLWindow6 *iface, REFIID riid, void **ppv)
1943 {
1944     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1945
1946     return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
1947 }
1948
1949 static ULONG WINAPI HTMLWindow6_AddRef(IHTMLWindow6 *iface)
1950 {
1951     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1952
1953     return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
1954 }
1955
1956 static ULONG WINAPI HTMLWindow6_Release(IHTMLWindow6 *iface)
1957 {
1958     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1959
1960     return IHTMLWindow2_Release(&This->IHTMLWindow2_iface);
1961 }
1962
1963 static HRESULT WINAPI HTMLWindow6_GetTypeInfoCount(IHTMLWindow6 *iface, UINT *pctinfo)
1964 {
1965     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1966
1967     return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo);
1968 }
1969
1970 static HRESULT WINAPI HTMLWindow6_GetTypeInfo(IHTMLWindow6 *iface, UINT iTInfo,
1971                                               LCID lcid, ITypeInfo **ppTInfo)
1972 {
1973     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1974
1975     return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo);
1976 }
1977
1978 static HRESULT WINAPI HTMLWindow6_GetIDsOfNames(IHTMLWindow6 *iface, REFIID riid,
1979                                                 LPOLESTR *rgszNames, UINT cNames,
1980                                                 LCID lcid, DISPID *rgDispId)
1981 {
1982     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1983
1984     return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid,
1985             rgDispId);
1986 }
1987
1988 static HRESULT WINAPI HTMLWindow6_Invoke(IHTMLWindow6 *iface, DISPID dispIdMember,
1989                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1990                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1991 {
1992     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1993
1994     return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
1995             pDispParams, pVarResult, pExcepInfo, puArgErr);
1996 }
1997
1998 static HRESULT WINAPI HTMLWindow6_put_XDomainRequest(IHTMLWindow6 *iface, VARIANT v)
1999 {
2000     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
2001     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
2002     return E_NOTIMPL;
2003 }
2004
2005 static HRESULT WINAPI HTMLWindow6_get_XDomainRequest(IHTMLWindow6 *iface, VARIANT *p)
2006 {
2007     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
2008     FIXME("(%p)->(%p)\n", This, p);
2009     return E_NOTIMPL;
2010 }
2011
2012 static HRESULT WINAPI HTMLWindow6_get_sessionStorage(IHTMLWindow6 *iface, IHTMLStorage **p)
2013 {
2014     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
2015
2016     FIXME("(%p)->(%p)\n", This, p);
2017
2018     if(!This->inner_window->session_storage) {
2019         HRESULT hres;
2020
2021         hres = create_storage(&This->inner_window->session_storage);
2022         if(FAILED(hres))
2023             return hres;
2024     }
2025
2026     IHTMLStorage_AddRef(This->inner_window->session_storage);
2027     *p = This->inner_window->session_storage;
2028     return S_OK;
2029 }
2030
2031 static HRESULT WINAPI HTMLWindow6_get_localStorage(IHTMLWindow6 *iface, IHTMLStorage **p)
2032 {
2033     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
2034     FIXME("(%p)->(%p)\n", This, p);
2035     return E_NOTIMPL;
2036 }
2037
2038 static HRESULT WINAPI HTMLWindow6_put_onhashchange(IHTMLWindow6 *iface, VARIANT v)
2039 {
2040     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
2041     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
2042     return E_NOTIMPL;
2043 }
2044
2045 static HRESULT WINAPI HTMLWindow6_get_onhashchange(IHTMLWindow6 *iface, VARIANT *p)
2046 {
2047     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
2048     FIXME("(%p)->(%p)\n", This, p);
2049     return E_NOTIMPL;
2050 }
2051
2052 static HRESULT WINAPI HTMLWindow6_get_maxConnectionsPerServer(IHTMLWindow6 *iface, LONG *p)
2053 {
2054     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
2055     FIXME("(%p)->(%p)\n", This, p);
2056     return E_NOTIMPL;
2057 }
2058
2059 static HRESULT WINAPI HTMLWindow6_postMessage(IHTMLWindow6 *iface, BSTR msg, VARIANT targetOrigin)
2060 {
2061     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
2062     FIXME("(%p)->(%s %s)\n", This, debugstr_w(msg), debugstr_variant(&targetOrigin));
2063     return E_NOTIMPL;
2064 }
2065
2066 static HRESULT WINAPI HTMLWindow6_toStaticHTML(IHTMLWindow6 *iface, BSTR bstrHTML, BSTR *pbstrStaticHTML)
2067 {
2068     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
2069     FIXME("(%p)->(%s %p)\n", This, debugstr_w(bstrHTML), pbstrStaticHTML);
2070     return E_NOTIMPL;
2071 }
2072
2073 static HRESULT WINAPI HTMLWindow6_put_onmessage(IHTMLWindow6 *iface, VARIANT v)
2074 {
2075     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
2076     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
2077     return E_NOTIMPL;
2078 }
2079
2080 static HRESULT WINAPI HTMLWindow6_get_onmessage(IHTMLWindow6 *iface, VARIANT *p)
2081 {
2082     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
2083     FIXME("(%p)->(%p)\n", This, p);
2084     return E_NOTIMPL;
2085 }
2086
2087 static HRESULT WINAPI HTMLWindow6_msWriteProfilerMark(IHTMLWindow6 *iface, BSTR bstrProfilerMark)
2088 {
2089     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
2090     FIXME("(%p)->(%s)\n", This, debugstr_w(bstrProfilerMark));
2091     return E_NOTIMPL;
2092 }
2093
2094 static const IHTMLWindow6Vtbl HTMLWindow6Vtbl = {
2095     HTMLWindow6_QueryInterface,
2096     HTMLWindow6_AddRef,
2097     HTMLWindow6_Release,
2098     HTMLWindow6_GetTypeInfoCount,
2099     HTMLWindow6_GetTypeInfo,
2100     HTMLWindow6_GetIDsOfNames,
2101     HTMLWindow6_Invoke,
2102     HTMLWindow6_put_XDomainRequest,
2103     HTMLWindow6_get_XDomainRequest,
2104     HTMLWindow6_get_sessionStorage,
2105     HTMLWindow6_get_localStorage,
2106     HTMLWindow6_put_onhashchange,
2107     HTMLWindow6_get_onhashchange,
2108     HTMLWindow6_get_maxConnectionsPerServer,
2109     HTMLWindow6_postMessage,
2110     HTMLWindow6_toStaticHTML,
2111     HTMLWindow6_put_onmessage,
2112     HTMLWindow6_get_onmessage,
2113     HTMLWindow6_msWriteProfilerMark
2114 };
2115
2116 static inline HTMLWindow *impl_from_IHTMLPrivateWindow(IHTMLPrivateWindow *iface)
2117 {
2118     return CONTAINING_RECORD(iface, HTMLWindow, IHTMLPrivateWindow_iface);
2119 }
2120
2121 static HRESULT WINAPI HTMLPrivateWindow_QueryInterface(IHTMLPrivateWindow *iface, REFIID riid, void **ppv)
2122 {
2123     HTMLWindow *This = impl_from_IHTMLPrivateWindow(iface);
2124
2125     return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
2126 }
2127
2128 static ULONG WINAPI HTMLPrivateWindow_AddRef(IHTMLPrivateWindow *iface)
2129 {
2130     HTMLWindow *This = impl_from_IHTMLPrivateWindow(iface);
2131
2132     return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
2133 }
2134
2135 static ULONG WINAPI HTMLPrivateWindow_Release(IHTMLPrivateWindow *iface)
2136 {
2137     HTMLWindow *This = impl_from_IHTMLPrivateWindow(iface);
2138
2139     return IHTMLWindow2_Release(&This->IHTMLWindow2_iface);
2140 }
2141
2142 static HRESULT WINAPI HTMLPrivateWindow_SuperNavigate(IHTMLPrivateWindow *iface, BSTR url, BSTR arg2, BSTR arg3,
2143         BSTR arg4, VARIANT *post_data_var, VARIANT *headers_var, ULONG flags)
2144 {
2145     HTMLWindow *This = impl_from_IHTMLPrivateWindow(iface);
2146     HTMLOuterWindow *window = This->outer_window;
2147     OLECHAR *translated_url = NULL;
2148     DWORD post_data_size = 0;
2149     BYTE *post_data = NULL;
2150     WCHAR *headers = NULL;
2151     IUri *uri;
2152     HRESULT hres;
2153
2154     TRACE("(%p)->(%s %s %s %s %s %s %x)\n", This, debugstr_w(url), debugstr_w(arg2), debugstr_w(arg3), debugstr_w(arg4),
2155           debugstr_variant(post_data_var), debugstr_variant(headers_var), flags);
2156
2157     if(window->doc_obj->hostui) {
2158         hres = IDocHostUIHandler_TranslateUrl(window->doc_obj->hostui, 0, url, &translated_url);
2159         if(hres != S_OK)
2160             translated_url = NULL;
2161     }
2162
2163     hres = create_uri(translated_url ? translated_url : url, 0, &uri);
2164     CoTaskMemFree(translated_url);
2165     if(FAILED(hres))
2166         return hres;
2167
2168     if(post_data_var) {
2169         if(V_VT(post_data_var) == (VT_ARRAY|VT_UI1)) {
2170             SafeArrayAccessData(V_ARRAY(post_data_var), (void**)&post_data);
2171             post_data_size = V_ARRAY(post_data_var)->rgsabound[0].cElements;
2172         }
2173     }
2174
2175     if(headers_var && V_VT(headers_var) != VT_EMPTY && V_VT(headers_var) != VT_ERROR) {
2176         if(V_VT(headers_var) != VT_BSTR)
2177             return E_INVALIDARG;
2178
2179         headers = V_BSTR(headers_var);
2180     }
2181
2182     hres = super_navigate(window, uri, BINDING_NAVIGATED, headers, post_data, post_data_size);
2183     IUri_Release(uri);
2184     if(post_data)
2185         SafeArrayUnaccessData(V_ARRAY(post_data_var));
2186
2187     return hres;
2188 }
2189
2190 static HRESULT WINAPI HTMLPrivateWindow_GetPendingUrl(IHTMLPrivateWindow *iface, BSTR *url)
2191 {
2192     HTMLWindow *This = impl_from_IHTMLPrivateWindow(iface);
2193     FIXME("(%p)->(%p)\n", This, url);
2194     return E_NOTIMPL;
2195 }
2196
2197 static HRESULT WINAPI HTMLPrivateWindow_SetPICSTarget(IHTMLPrivateWindow *iface, IOleCommandTarget *cmdtrg)
2198 {
2199     HTMLWindow *This = impl_from_IHTMLPrivateWindow(iface);
2200     FIXME("(%p)->(%p)\n", This, cmdtrg);
2201     return E_NOTIMPL;
2202 }
2203
2204 static HRESULT WINAPI HTMLPrivateWindow_PICSComplete(IHTMLPrivateWindow *iface, int arg)
2205 {
2206     HTMLWindow *This = impl_from_IHTMLPrivateWindow(iface);
2207     FIXME("(%p)->(%x)\n", This, arg);
2208     return E_NOTIMPL;
2209 }
2210
2211 static HRESULT WINAPI HTMLPrivateWindow_FindWindowByName(IHTMLPrivateWindow *iface, LPCWSTR name, IHTMLWindow2 **ret)
2212 {
2213     HTMLWindow *This = impl_from_IHTMLPrivateWindow(iface);
2214     FIXME("(%p)->(%s %p)\n", This, debugstr_w(name), ret);
2215     return E_NOTIMPL;
2216 }
2217
2218 static HRESULT WINAPI HTMLPrivateWindow_GetAddressBarUrl(IHTMLPrivateWindow *iface, BSTR *url)
2219 {
2220     HTMLWindow *This = impl_from_IHTMLPrivateWindow(iface);
2221     TRACE("(%p)->(%p)\n", This, url);
2222
2223     if(!url)
2224         return E_INVALIDARG;
2225
2226     *url = SysAllocString(This->outer_window->url);
2227     return S_OK;
2228 }
2229
2230 static const IHTMLPrivateWindowVtbl HTMLPrivateWindowVtbl = {
2231     HTMLPrivateWindow_QueryInterface,
2232     HTMLPrivateWindow_AddRef,
2233     HTMLPrivateWindow_Release,
2234     HTMLPrivateWindow_SuperNavigate,
2235     HTMLPrivateWindow_GetPendingUrl,
2236     HTMLPrivateWindow_SetPICSTarget,
2237     HTMLPrivateWindow_PICSComplete,
2238     HTMLPrivateWindow_FindWindowByName,
2239     HTMLPrivateWindow_GetAddressBarUrl
2240 };
2241
2242 static inline HTMLWindow *impl_from_ITravelLogClient(ITravelLogClient *iface)
2243 {
2244     return CONTAINING_RECORD(iface, HTMLWindow, ITravelLogClient_iface);
2245 }
2246
2247 static HRESULT WINAPI TravelLogClient_QueryInterface(ITravelLogClient *iface, REFIID riid, void **ppv)
2248 {
2249     HTMLWindow *This = impl_from_ITravelLogClient(iface);
2250
2251     return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
2252 }
2253
2254 static ULONG WINAPI TravelLogClient_AddRef(ITravelLogClient *iface)
2255 {
2256     HTMLWindow *This = impl_from_ITravelLogClient(iface);
2257
2258     return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
2259 }
2260
2261 static ULONG WINAPI TravelLogClient_Release(ITravelLogClient *iface)
2262 {
2263     HTMLWindow *This = impl_from_ITravelLogClient(iface);
2264
2265     return IHTMLWindow2_Release(&This->IHTMLWindow2_iface);
2266 }
2267
2268 static HRESULT WINAPI TravelLogClient_FindWindowByIndex(ITravelLogClient *iface, DWORD dwID, IUnknown **ppunk)
2269 {
2270     HTMLWindow *This = impl_from_ITravelLogClient(iface);
2271
2272     FIXME("(%p)->(%d %p) semi-stub\n", This, dwID, ppunk);
2273
2274     *ppunk = NULL;
2275     return E_FAIL;
2276 }
2277
2278 static HRESULT WINAPI TravelLogClient_GetWindowData(ITravelLogClient *iface, IStream *pStream, LPWINDOWDATA pWinData)
2279 {
2280     HTMLWindow *This = impl_from_ITravelLogClient(iface);
2281     FIXME("(%p)->(%p %p)\n", This, pStream, pWinData);
2282     return E_NOTIMPL;
2283 }
2284
2285 static HRESULT WINAPI TravelLogClient_LoadHistoryPosition(ITravelLogClient *iface, LPWSTR pszUrlLocation, DWORD dwPosition)
2286 {
2287     HTMLWindow *This = impl_from_ITravelLogClient(iface);
2288     FIXME("(%p)->(%s %d)\n", This, debugstr_w(pszUrlLocation), dwPosition);
2289     return E_NOTIMPL;
2290 }
2291
2292 static const ITravelLogClientVtbl TravelLogClientVtbl = {
2293     TravelLogClient_QueryInterface,
2294     TravelLogClient_AddRef,
2295     TravelLogClient_Release,
2296     TravelLogClient_FindWindowByIndex,
2297     TravelLogClient_GetWindowData,
2298     TravelLogClient_LoadHistoryPosition
2299 };
2300
2301 static inline HTMLWindow *impl_from_IObjectIdentity(IObjectIdentity *iface)
2302 {
2303     return CONTAINING_RECORD(iface, HTMLWindow, IObjectIdentity_iface);
2304 }
2305
2306 static HRESULT WINAPI ObjectIdentity_QueryInterface(IObjectIdentity *iface, REFIID riid, void **ppv)
2307 {
2308     HTMLWindow *This = impl_from_IObjectIdentity(iface);
2309
2310     return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
2311 }
2312
2313 static ULONG WINAPI ObjectIdentity_AddRef(IObjectIdentity *iface)
2314 {
2315     HTMLWindow *This = impl_from_IObjectIdentity(iface);
2316
2317     return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
2318 }
2319
2320 static ULONG WINAPI ObjectIdentity_Release(IObjectIdentity *iface)
2321 {
2322     HTMLWindow *This = impl_from_IObjectIdentity(iface);
2323
2324     return IHTMLWindow2_Release(&This->IHTMLWindow2_iface);
2325 }
2326
2327 static HRESULT WINAPI ObjectIdentity_IsEqualObject(IObjectIdentity *iface, IUnknown *unk)
2328 {
2329     HTMLWindow *This = impl_from_IObjectIdentity(iface);
2330     IServiceProvider *sp;
2331     HRESULT hres;
2332
2333     TRACE("(%p)->(%p)\n", This, unk);
2334
2335     hres = IUnknown_QueryInterface(unk, &IID_IServiceProvider, (void**)&sp);
2336     if(hres != S_OK)
2337         return hres;
2338
2339     hres = &This->inner_window->base.IServiceProvider_iface==sp ||
2340         &This->outer_window->base.IServiceProvider_iface==sp ? S_OK : S_FALSE;
2341     IServiceProvider_Release(sp);
2342     return hres;
2343 }
2344
2345 static const IObjectIdentityVtbl ObjectIdentityVtbl = {
2346     ObjectIdentity_QueryInterface,
2347     ObjectIdentity_AddRef,
2348     ObjectIdentity_Release,
2349     ObjectIdentity_IsEqualObject
2350 };
2351
2352 static inline HTMLWindow *impl_from_IDispatchEx(IDispatchEx *iface)
2353 {
2354     return CONTAINING_RECORD(iface, HTMLWindow, IDispatchEx_iface);
2355 }
2356
2357 static HRESULT WINAPI WindowDispEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
2358 {
2359     HTMLWindow *This = impl_from_IDispatchEx(iface);
2360
2361     return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
2362 }
2363
2364 static ULONG WINAPI WindowDispEx_AddRef(IDispatchEx *iface)
2365 {
2366     HTMLWindow *This = impl_from_IDispatchEx(iface);
2367
2368     return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
2369 }
2370
2371 static ULONG WINAPI WindowDispEx_Release(IDispatchEx *iface)
2372 {
2373     HTMLWindow *This = impl_from_IDispatchEx(iface);
2374
2375     return IHTMLWindow2_Release(&This->IHTMLWindow2_iface);
2376 }
2377
2378 static HRESULT WINAPI WindowDispEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
2379 {
2380     HTMLWindow *This = impl_from_IDispatchEx(iface);
2381
2382     TRACE("(%p)->(%p)\n", This, pctinfo);
2383
2384     return IDispatchEx_GetTypeInfoCount(&This->inner_window->dispex.IDispatchEx_iface, pctinfo);
2385 }
2386
2387 static HRESULT WINAPI WindowDispEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
2388                                                LCID lcid, ITypeInfo **ppTInfo)
2389 {
2390     HTMLWindow *This = impl_from_IDispatchEx(iface);
2391
2392     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
2393
2394     return IDispatchEx_GetTypeInfo(&This->inner_window->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
2395 }
2396
2397 static HRESULT WINAPI WindowDispEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
2398                                                  LPOLESTR *rgszNames, UINT cNames,
2399                                                  LCID lcid, DISPID *rgDispId)
2400 {
2401     HTMLWindow *This = impl_from_IDispatchEx(iface);
2402     UINT i;
2403     HRESULT hres;
2404
2405     WARN("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
2406           lcid, rgDispId);
2407
2408     for(i=0; i < cNames; i++) {
2409         /* We shouldn't use script's IDispatchEx here, so we shouldn't use GetDispID */
2410         hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, rgszNames[i], 0, rgDispId+i);
2411         if(FAILED(hres))
2412             return hres;
2413     }
2414
2415     return S_OK;
2416 }
2417
2418 static HRESULT WINAPI WindowDispEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
2419                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
2420                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
2421 {
2422     HTMLWindow *This = impl_from_IDispatchEx(iface);
2423
2424     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
2425           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2426
2427     /* FIXME: Use script dispatch */
2428
2429     return IDispatchEx_Invoke(&This->inner_window->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
2430             pDispParams, pVarResult, pExcepInfo, puArgErr);
2431 }
2432
2433 static global_prop_t *alloc_global_prop(HTMLInnerWindow *This, global_prop_type_t type, BSTR name)
2434 {
2435     if(This->global_prop_cnt == This->global_prop_size) {
2436         global_prop_t *new_props;
2437         DWORD new_size;
2438
2439         if(This->global_props) {
2440             new_size = This->global_prop_size*2;
2441             new_props = heap_realloc(This->global_props, new_size*sizeof(global_prop_t));
2442         }else {
2443             new_size = 16;
2444             new_props = heap_alloc(new_size*sizeof(global_prop_t));
2445         }
2446         if(!new_props)
2447             return NULL;
2448         This->global_props = new_props;
2449         This->global_prop_size = new_size;
2450     }
2451
2452     This->global_props[This->global_prop_cnt].name = heap_strdupW(name);
2453     if(!This->global_props[This->global_prop_cnt].name)
2454         return NULL;
2455
2456     This->global_props[This->global_prop_cnt].type = type;
2457     return This->global_props + This->global_prop_cnt++;
2458 }
2459
2460 static inline DWORD prop_to_dispid(HTMLInnerWindow *This, global_prop_t *prop)
2461 {
2462     return MSHTML_DISPID_CUSTOM_MIN + (prop-This->global_props);
2463 }
2464
2465 HRESULT search_window_props(HTMLInnerWindow *This, BSTR bstrName, DWORD grfdex, DISPID *pid)
2466 {
2467     DWORD i;
2468     ScriptHost *script_host;
2469     DISPID id;
2470
2471     for(i=0; i < This->global_prop_cnt; i++) {
2472         /* FIXME: case sensitivity */
2473         if(!strcmpW(This->global_props[i].name, bstrName)) {
2474             *pid = MSHTML_DISPID_CUSTOM_MIN+i;
2475             return S_OK;
2476         }
2477     }
2478
2479     if(find_global_prop(This->base.inner_window, bstrName, grfdex, &script_host, &id)) {
2480         global_prop_t *prop;
2481
2482         prop = alloc_global_prop(This, GLOBAL_SCRIPTVAR, bstrName);
2483         if(!prop)
2484             return E_OUTOFMEMORY;
2485
2486         prop->script_host = script_host;
2487         prop->id = id;
2488
2489         *pid = prop_to_dispid(This, prop);
2490         return S_OK;
2491     }
2492
2493     return DISP_E_UNKNOWNNAME;
2494 }
2495
2496 static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
2497 {
2498     HTMLWindow *This = impl_from_IDispatchEx(iface);
2499     HTMLInnerWindow *window = This->inner_window;
2500     HRESULT hres;
2501
2502     TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
2503
2504     hres = search_window_props(window, bstrName, grfdex, pid);
2505     if(hres != DISP_E_UNKNOWNNAME)
2506         return hres;
2507
2508     hres = IDispatchEx_GetDispID(&window->base.inner_window->dispex.IDispatchEx_iface, bstrName, grfdex, pid);
2509     if(hres != DISP_E_UNKNOWNNAME)
2510         return hres;
2511
2512     if(This->outer_window) {
2513         HTMLOuterWindow *frame;
2514
2515         hres = get_frame_by_name(This->outer_window, bstrName, FALSE, &frame);
2516         if(SUCCEEDED(hres) && frame) {
2517             global_prop_t *prop;
2518
2519             IHTMLWindow2_Release(&frame->base.IHTMLWindow2_iface);
2520
2521             prop = alloc_global_prop(window, GLOBAL_FRAMEVAR, bstrName);
2522             if(!prop)
2523                 return E_OUTOFMEMORY;
2524
2525             *pid = prop_to_dispid(window, prop);
2526             return S_OK;
2527         }
2528     }
2529
2530     if(window->doc) {
2531         global_prop_t *prop;
2532         IHTMLElement *elem;
2533
2534         hres = IHTMLDocument3_getElementById(&window->base.inner_window->doc->basedoc.IHTMLDocument3_iface,
2535                                              bstrName, &elem);
2536         if(SUCCEEDED(hres) && elem) {
2537             IHTMLElement_Release(elem);
2538
2539             prop = alloc_global_prop(window, GLOBAL_ELEMENTVAR, bstrName);
2540             if(!prop)
2541                 return E_OUTOFMEMORY;
2542
2543             *pid = prop_to_dispid(window, prop);
2544             return S_OK;
2545         }
2546     }
2547
2548     return DISP_E_UNKNOWNNAME;
2549 }
2550
2551 static HRESULT WINAPI WindowDispEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
2552         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
2553 {
2554     HTMLWindow *This = impl_from_IDispatchEx(iface);
2555     HTMLInnerWindow *window = This->inner_window;
2556
2557     TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
2558
2559     if(id == DISPID_IHTMLWINDOW2_LOCATION && (wFlags & DISPATCH_PROPERTYPUT)) {
2560         HTMLLocation *location;
2561         HRESULT hres;
2562
2563         TRACE("forwarding to location.href\n");
2564
2565         hres = get_location(window, &location);
2566         if(FAILED(hres))
2567             return hres;
2568
2569         hres = IDispatchEx_InvokeEx(&location->dispex.IDispatchEx_iface, DISPID_VALUE, lcid,
2570                 wFlags, pdp, pvarRes, pei, pspCaller);
2571         IHTMLLocation_Release(&location->IHTMLLocation_iface);
2572         return hres;
2573     }
2574
2575     return IDispatchEx_InvokeEx(&window->dispex.IDispatchEx_iface, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
2576 }
2577
2578 static HRESULT WINAPI WindowDispEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
2579 {
2580     HTMLWindow *This = impl_from_IDispatchEx(iface);
2581
2582     TRACE("(%p)->(%s %x)\n", This, debugstr_w(bstrName), grfdex);
2583
2584     return IDispatchEx_DeleteMemberByName(&This->inner_window->dispex.IDispatchEx_iface, bstrName, grfdex);
2585 }
2586
2587 static HRESULT WINAPI WindowDispEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
2588 {
2589     HTMLWindow *This = impl_from_IDispatchEx(iface);
2590
2591     TRACE("(%p)->(%x)\n", This, id);
2592
2593     return IDispatchEx_DeleteMemberByDispID(&This->inner_window->dispex.IDispatchEx_iface, id);
2594 }
2595
2596 static HRESULT WINAPI WindowDispEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
2597 {
2598     HTMLWindow *This = impl_from_IDispatchEx(iface);
2599
2600     TRACE("(%p)->(%x %x %p)\n", This, id, grfdexFetch, pgrfdex);
2601
2602     return IDispatchEx_GetMemberProperties(&This->inner_window->dispex.IDispatchEx_iface, id, grfdexFetch,
2603             pgrfdex);
2604 }
2605
2606 static HRESULT WINAPI WindowDispEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
2607 {
2608     HTMLWindow *This = impl_from_IDispatchEx(iface);
2609
2610     TRACE("(%p)->(%x %p)\n", This, id, pbstrName);
2611
2612     return IDispatchEx_GetMemberName(&This->inner_window->dispex.IDispatchEx_iface, id, pbstrName);
2613 }
2614
2615 static HRESULT WINAPI WindowDispEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
2616 {
2617     HTMLWindow *This = impl_from_IDispatchEx(iface);
2618
2619     TRACE("(%p)->(%x %x %p)\n", This, grfdex, id, pid);
2620
2621     return IDispatchEx_GetNextDispID(&This->inner_window->dispex.IDispatchEx_iface, grfdex, id, pid);
2622 }
2623
2624 static HRESULT WINAPI WindowDispEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
2625 {
2626     HTMLWindow *This = impl_from_IDispatchEx(iface);
2627
2628     TRACE("(%p)->(%p)\n", This, ppunk);
2629
2630     *ppunk = NULL;
2631     return S_OK;
2632 }
2633
2634 static const IDispatchExVtbl WindowDispExVtbl = {
2635     WindowDispEx_QueryInterface,
2636     WindowDispEx_AddRef,
2637     WindowDispEx_Release,
2638     WindowDispEx_GetTypeInfoCount,
2639     WindowDispEx_GetTypeInfo,
2640     WindowDispEx_GetIDsOfNames,
2641     WindowDispEx_Invoke,
2642     WindowDispEx_GetDispID,
2643     WindowDispEx_InvokeEx,
2644     WindowDispEx_DeleteMemberByName,
2645     WindowDispEx_DeleteMemberByDispID,
2646     WindowDispEx_GetMemberProperties,
2647     WindowDispEx_GetMemberName,
2648     WindowDispEx_GetNextDispID,
2649     WindowDispEx_GetNameSpaceParent
2650 };
2651
2652 static inline HTMLWindow *impl_from_IServiceProvider(IServiceProvider *iface)
2653 {
2654     return CONTAINING_RECORD(iface, HTMLWindow, IServiceProvider_iface);
2655 }
2656
2657 static HRESULT WINAPI HTMLWindowSP_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
2658 {
2659     HTMLWindow *This = impl_from_IServiceProvider(iface);
2660     return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
2661 }
2662
2663 static ULONG WINAPI HTMLWindowSP_AddRef(IServiceProvider *iface)
2664 {
2665     HTMLWindow *This = impl_from_IServiceProvider(iface);
2666     return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
2667 }
2668
2669 static ULONG WINAPI HTMLWindowSP_Release(IServiceProvider *iface)
2670 {
2671     HTMLWindow *This = impl_from_IServiceProvider(iface);
2672     return IHTMLWindow2_Release(&This->IHTMLWindow2_iface);
2673 }
2674
2675 static HRESULT WINAPI HTMLWindowSP_QueryService(IServiceProvider *iface, REFGUID guidService, REFIID riid, void **ppv)
2676 {
2677     HTMLWindow *This = impl_from_IServiceProvider(iface);
2678
2679     if(IsEqualGUID(guidService, &IID_IHTMLWindow2)) {
2680         TRACE("IID_IHTMLWindow2\n");
2681         return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
2682     }
2683
2684     TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
2685
2686     if(!This->outer_window->doc_obj)
2687         return E_NOINTERFACE;
2688
2689     return IServiceProvider_QueryService(&This->outer_window->doc_obj->basedoc.IServiceProvider_iface,
2690             guidService, riid, ppv);
2691 }
2692
2693 static const IServiceProviderVtbl ServiceProviderVtbl = {
2694     HTMLWindowSP_QueryInterface,
2695     HTMLWindowSP_AddRef,
2696     HTMLWindowSP_Release,
2697     HTMLWindowSP_QueryService
2698 };
2699
2700 static inline HTMLInnerWindow *impl_from_DispatchEx(DispatchEx *iface)
2701 {
2702     return CONTAINING_RECORD(iface, HTMLInnerWindow, dispex);
2703 }
2704
2705 static HRESULT HTMLWindow_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
2706         VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
2707 {
2708     HTMLInnerWindow *This = impl_from_DispatchEx(dispex);
2709     global_prop_t *prop;
2710     DWORD idx;
2711     HRESULT hres;
2712
2713     idx = id - MSHTML_DISPID_CUSTOM_MIN;
2714     if(idx >= This->global_prop_cnt)
2715         return DISP_E_MEMBERNOTFOUND;
2716
2717     prop = This->global_props+idx;
2718
2719     switch(prop->type) {
2720     case GLOBAL_SCRIPTVAR: {
2721         IDispatchEx *iface;
2722         IDispatch *disp;
2723
2724         disp = get_script_disp(prop->script_host);
2725         if(!disp)
2726             return E_UNEXPECTED;
2727
2728         hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&iface);
2729         if(SUCCEEDED(hres)) {
2730             TRACE("%s >>>\n", debugstr_w(prop->name));
2731             hres = IDispatchEx_InvokeEx(iface, prop->id, lcid, flags, params, res, ei, caller);
2732             if(hres == S_OK)
2733                 TRACE("%s <<<\n", debugstr_w(prop->name));
2734             else
2735                 WARN("%s <<< %08x\n", debugstr_w(prop->name), hres);
2736             IDispatchEx_Release(iface);
2737         }else {
2738             FIXME("No IDispatchEx\n");
2739         }
2740         IDispatch_Release(disp);
2741         break;
2742     }
2743     case GLOBAL_ELEMENTVAR:
2744         switch(flags) {
2745         case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
2746         case DISPATCH_PROPERTYGET: {
2747             IHTMLElement *elem;
2748
2749             hres = IHTMLDocument3_getElementById(&This->base.inner_window->doc->basedoc.IHTMLDocument3_iface,
2750                     prop->name, &elem);
2751             if(FAILED(hres))
2752                 return hres;
2753
2754             if(!elem)
2755                 return DISP_E_MEMBERNOTFOUND;
2756
2757             V_VT(res) = VT_DISPATCH;
2758             V_DISPATCH(res) = (IDispatch*)elem;
2759             return S_OK;
2760         }
2761         case DISPATCH_PROPERTYPUT: {
2762             DISPID dispex_id;
2763
2764             hres = dispex_get_dynid(&This->dispex, prop->name, &dispex_id);
2765             if(FAILED(hres))
2766                 return hres;
2767
2768             prop->type = GLOBAL_DISPEXVAR;
2769             prop->id = dispex_id;
2770             return IDispatchEx_InvokeEx(&This->dispex.IDispatchEx_iface, dispex_id, 0, flags, params, res, ei, caller);
2771         }
2772         default:
2773             FIXME("Not supported flags: %x\n", flags);
2774             return E_NOTIMPL;
2775         }
2776     case GLOBAL_FRAMEVAR:
2777         if(!This->base.outer_window)
2778             return E_UNEXPECTED;
2779
2780         switch(flags) {
2781         case DISPATCH_PROPERTYGET: {
2782             HTMLOuterWindow *frame;
2783
2784             hres = get_frame_by_name(This->base.outer_window, prop->name, FALSE, &frame);
2785             if(FAILED(hres))
2786                 return hres;
2787
2788             if(!frame)
2789                 return DISP_E_MEMBERNOTFOUND;
2790
2791             V_VT(res) = VT_DISPATCH;
2792             V_DISPATCH(res) = (IDispatch*)&frame->base.inner_window->base.IHTMLWindow2_iface;
2793             IDispatch_AddRef(V_DISPATCH(res));
2794             return S_OK;
2795         }
2796         default:
2797             FIXME("Not supported flags: %x\n", flags);
2798             return E_NOTIMPL;
2799         }
2800     case GLOBAL_DISPEXVAR:
2801         return IDispatchEx_InvokeEx(&This->dispex.IDispatchEx_iface, prop->id, 0, flags, params, res, ei, caller);
2802     default:
2803         ERR("invalid type %d\n", prop->type);
2804         hres = DISP_E_MEMBERNOTFOUND;
2805     }
2806
2807     return hres;
2808 }
2809
2810
2811 static const dispex_static_data_vtbl_t HTMLWindow_dispex_vtbl = {
2812     NULL,
2813     NULL,
2814     HTMLWindow_invoke,
2815     NULL
2816 };
2817
2818 static const tid_t HTMLWindow_iface_tids[] = {
2819     IHTMLWindow2_tid,
2820     IHTMLWindow3_tid,
2821     IHTMLWindow4_tid,
2822     IHTMLWindow6_tid,
2823     0
2824 };
2825
2826 static dispex_static_data_t HTMLWindow_dispex = {
2827     &HTMLWindow_dispex_vtbl,
2828     DispHTMLWindow2_tid,
2829     NULL,
2830     HTMLWindow_iface_tids
2831 };
2832
2833 static void *alloc_window(size_t size)
2834 {
2835     HTMLWindow *window;
2836
2837     window = heap_alloc_zero(size);
2838     if(!window)
2839         return NULL;
2840
2841     window->IHTMLWindow2_iface.lpVtbl = &HTMLWindow2Vtbl;
2842     window->IHTMLWindow3_iface.lpVtbl = &HTMLWindow3Vtbl;
2843     window->IHTMLWindow4_iface.lpVtbl = &HTMLWindow4Vtbl;
2844     window->IHTMLWindow5_iface.lpVtbl = &HTMLWindow5Vtbl;
2845     window->IHTMLWindow6_iface.lpVtbl = &HTMLWindow6Vtbl;
2846     window->IHTMLPrivateWindow_iface.lpVtbl = &HTMLPrivateWindowVtbl;
2847     window->IDispatchEx_iface.lpVtbl = &WindowDispExVtbl;
2848     window->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl;
2849     window->ITravelLogClient_iface.lpVtbl = &TravelLogClientVtbl;
2850     window->IObjectIdentity_iface.lpVtbl = &ObjectIdentityVtbl;
2851     window->ref = 1;
2852
2853     return window;
2854 }
2855
2856 static HRESULT create_inner_window(HTMLOuterWindow *outer_window, IMoniker *mon, HTMLInnerWindow **ret)
2857 {
2858     HTMLInnerWindow *window;
2859
2860     window = alloc_window(sizeof(HTMLInnerWindow));
2861     if(!window)
2862         return E_OUTOFMEMORY;
2863
2864     list_init(&window->script_hosts);
2865     list_init(&window->bindings);
2866     list_init(&window->script_queue);
2867
2868     window->base.outer_window = outer_window;
2869     window->base.inner_window = window;
2870
2871     init_dispex(&window->dispex, (IUnknown*)&window->base.IHTMLWindow2_iface, &HTMLWindow_dispex);
2872
2873     window->task_magic = get_task_target_magic();
2874
2875     if(mon) {
2876         IMoniker_AddRef(mon);
2877         window->mon = mon;
2878     }
2879
2880     *ret = window;
2881     return S_OK;
2882 }
2883
2884 HRESULT HTMLOuterWindow_Create(HTMLDocumentObj *doc_obj, nsIDOMWindow *nswindow,
2885         HTMLOuterWindow *parent, HTMLOuterWindow **ret)
2886 {
2887     HTMLOuterWindow *window;
2888     HRESULT hres;
2889
2890     window = alloc_window(sizeof(HTMLOuterWindow));
2891     if(!window)
2892         return E_OUTOFMEMORY;
2893
2894     window->base.outer_window = window;
2895     window->base.inner_window = NULL;
2896
2897     window->window_ref = heap_alloc(sizeof(windowref_t));
2898     if(!window->window_ref) {
2899         heap_free(window);
2900         return E_OUTOFMEMORY;
2901     }
2902
2903     window->doc_obj = doc_obj;
2904
2905     window->window_ref->window = window;
2906     window->window_ref->ref = 1;
2907
2908     if(nswindow) {
2909         nsIDOMWindow_AddRef(nswindow);
2910         window->nswindow = nswindow;
2911     }
2912
2913     window->scriptmode = parent ? parent->scriptmode : SCRIPTMODE_GECKO;
2914     window->readystate = READYSTATE_UNINITIALIZED;
2915
2916     hres = create_pending_window(window, NULL);
2917     if(SUCCEEDED(hres))
2918         hres = update_window_doc(window->pending_window);
2919     if(FAILED(hres)) {
2920         IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
2921         return hres;
2922     }
2923
2924     hres = CoInternetCreateSecurityManager(NULL, &window->secmgr, 0);
2925     if(FAILED(hres)) {
2926         IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
2927         return hres;
2928     }
2929
2930     window->task_magic = get_task_target_magic();
2931
2932     list_init(&window->children);
2933     list_add_head(&window_list, &window->entry);
2934
2935     if(parent) {
2936         IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
2937
2938         window->parent = parent;
2939         list_add_tail(&parent->children, &window->sibling_entry);
2940     }
2941
2942     TRACE("%p inner_window %p\n", window, window->base.inner_window);
2943
2944     *ret = window;
2945     return S_OK;
2946 }
2947
2948 HRESULT create_pending_window(HTMLOuterWindow *outer_window, nsChannelBSC *channelbsc)
2949 {
2950     HTMLInnerWindow *pending_window;
2951     HRESULT hres;
2952
2953     hres = create_inner_window(outer_window, outer_window->mon /* FIXME */, &pending_window);
2954     if(FAILED(hres))
2955         return hres;
2956
2957     if(channelbsc) {
2958         IBindStatusCallback_AddRef(&channelbsc->bsc.IBindStatusCallback_iface);
2959         pending_window->bscallback = channelbsc;
2960     }
2961
2962     if(outer_window->pending_window) {
2963         abort_window_bindings(outer_window->pending_window);
2964         outer_window->pending_window->base.outer_window = NULL;
2965         IHTMLWindow2_Release(&outer_window->pending_window->base.IHTMLWindow2_iface);
2966     }
2967
2968     outer_window->pending_window = pending_window;
2969     return S_OK;
2970 }
2971
2972 HRESULT update_window_doc(HTMLInnerWindow *window)
2973 {
2974     HTMLOuterWindow *outer_window = window->base.outer_window;
2975     nsIDOMHTMLDocument *nshtmldoc;
2976     nsIDOMDocument *nsdoc;
2977     nsresult nsres;
2978     HRESULT hres;
2979
2980     assert(!window->doc);
2981
2982     if(!outer_window) {
2983         ERR("NULL outer window\n");
2984         return E_UNEXPECTED;
2985     }
2986
2987     nsres = nsIDOMWindow_GetDocument(outer_window->nswindow, &nsdoc);
2988     if(NS_FAILED(nsres) || !nsdoc) {
2989         ERR("GetDocument failed: %08x\n", nsres);
2990         return E_FAIL;
2991     }
2992
2993     nsres = nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMHTMLDocument, (void**)&nshtmldoc);
2994     nsIDOMDocument_Release(nsdoc);
2995     if(NS_FAILED(nsres)) {
2996         ERR("Could not get nsIDOMHTMLDocument iface: %08x\n", nsres);
2997         return E_FAIL;
2998     }
2999
3000     hres = create_doc_from_nsdoc(nshtmldoc, outer_window->doc_obj, window, &window->doc);
3001     nsIDOMHTMLDocument_Release(nshtmldoc);
3002     if(FAILED(hres))
3003         return hres;
3004
3005     if(outer_window->doc_obj->usermode == EDITMODE) {
3006         nsAString mode_str;
3007         nsresult nsres;
3008
3009         static const PRUnichar onW[] = {'o','n',0};
3010
3011         nsAString_InitDepend(&mode_str, onW);
3012         nsres = nsIDOMHTMLDocument_SetDesignMode(window->doc->nsdoc, &mode_str);
3013         nsAString_Finish(&mode_str);
3014         if(NS_FAILED(nsres))
3015             ERR("SetDesignMode failed: %08x\n", nsres);
3016     }
3017
3018     if(window != outer_window->pending_window) {
3019         ERR("not current pending window\n");
3020         return S_OK;
3021     }
3022
3023     if(outer_window->base.inner_window)
3024         detach_inner_window(outer_window->base.inner_window);
3025     outer_window->base.inner_window = window;
3026     outer_window->pending_window = NULL;
3027
3028     if(outer_window->doc_obj->basedoc.window == outer_window || !outer_window->doc_obj->basedoc.window) {
3029         if(outer_window->doc_obj->basedoc.doc_node)
3030             htmldoc_release(&outer_window->doc_obj->basedoc.doc_node->basedoc);
3031         outer_window->doc_obj->basedoc.doc_node = window->doc;
3032         htmldoc_addref(&window->doc->basedoc);
3033     }
3034
3035     return hres;
3036 }
3037
3038 HTMLOuterWindow *nswindow_to_window(const nsIDOMWindow *nswindow)
3039 {
3040     HTMLOuterWindow *iter;
3041
3042     LIST_FOR_EACH_ENTRY(iter, &window_list, HTMLOuterWindow, entry) {
3043         if(iter->nswindow == nswindow)
3044             return iter;
3045     }
3046
3047     return NULL;
3048 }