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