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