shlwapi: Allow ' ' in hostname and password in UrlGetPart.
[wine] / dlls / mshtml / htmlwindow.c
1 /*
2  * Copyright 2006 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include <stdarg.h>
20
21 #define COBJMACROS
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "ole2.h"
27 #include "mshtmdid.h"
28
29 #include "wine/debug.h"
30 #include "wine/unicode.h"
31
32 #include "mshtml_private.h"
33 #include "htmlevent.h"
34 #include "resource.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
37
38 static struct list window_list = LIST_INIT(window_list);
39
40 static void window_set_docnode(HTMLWindow *window, HTMLDocumentNode *doc_node)
41 {
42     if(window->doc) {
43         abort_document_bindings(window->doc);
44         window->doc->basedoc.window = NULL;
45         htmldoc_release(&window->doc->basedoc);
46     }
47     window->doc = doc_node;
48     if(doc_node)
49         htmldoc_addref(&doc_node->basedoc);
50
51     if(window->doc_obj && window->doc_obj->basedoc.window == window) {
52         if(window->doc_obj->basedoc.doc_node)
53             htmldoc_release(&window->doc_obj->basedoc.doc_node->basedoc);
54         window->doc_obj->basedoc.doc_node = doc_node;
55         if(doc_node)
56             htmldoc_addref(&doc_node->basedoc);
57     }
58 }
59
60 nsIDOMWindow *get_nsdoc_window(nsIDOMDocument *nsdoc)
61 {
62     nsIDOMDocumentView *nsdocview;
63     nsIDOMAbstractView *nsview;
64     nsIDOMWindow *nswindow;
65     nsresult nsres;
66
67     nsres = nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMDocumentView, (void**)&nsdocview);
68     nsIDOMDocument_Release(nsdoc);
69     if(NS_FAILED(nsres)) {
70         ERR("Could not get nsIDOMDocumentView iface: %08x\n", nsres);
71         return NULL;
72     }
73
74     nsres = nsIDOMDocumentView_GetDefaultView(nsdocview, &nsview);
75     nsIDOMDocumentView_Release(nsview);
76     if(NS_FAILED(nsres)) {
77         ERR("GetDefaultView failed: %08x\n", nsres);
78         return NULL;
79     }
80
81     nsres = nsIDOMAbstractView_QueryInterface(nsview, &IID_nsIDOMWindow, (void**)&nswindow);
82     nsIDOMAbstractView_Release(nsview);
83     if(NS_FAILED(nsres)) {
84         ERR("Coult not get nsIDOMWindow iface: %08x\n", nsres);
85         return NULL;
86     }
87
88     return nswindow;
89 }
90
91 static void release_children(HTMLWindow *This)
92 {
93     HTMLWindow *child;
94
95     while(!list_empty(&This->children)) {
96         child = LIST_ENTRY(list_tail(&This->children), HTMLWindow, sibling_entry);
97
98         list_remove(&child->sibling_entry);
99         child->parent = NULL;
100         IHTMLWindow2_Release(HTMLWINDOW2(child));
101     }
102 }
103
104 static HRESULT get_location(HTMLWindow *This, HTMLLocation **ret)
105 {
106     if(This->location) {
107         IHTMLLocation_AddRef(HTMLLOCATION(This->location));
108     }else {
109         HRESULT hres;
110
111         hres = HTMLLocation_Create(This, &This->location);
112         if(FAILED(hres))
113             return hres;
114     }
115
116     *ret = This->location;
117     return S_OK;
118 }
119
120 #define HTMLWINDOW2_THIS(iface) DEFINE_THIS(HTMLWindow, HTMLWindow2, iface)
121
122 static HRESULT WINAPI HTMLWindow2_QueryInterface(IHTMLWindow2 *iface, REFIID riid, void **ppv)
123 {
124     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
125
126     *ppv = NULL;
127
128     if(IsEqualGUID(&IID_IUnknown, riid)) {
129         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
130         *ppv = HTMLWINDOW2(This);
131     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
132         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
133         *ppv = HTMLWINDOW2(This);
134     }else if(IsEqualGUID(&IID_IDispatchEx, riid)) {
135         TRACE("(%p)->(IID_IDispatchEx %p)\n", This, ppv);
136         *ppv = DISPATCHEX(This);
137     }else if(IsEqualGUID(&IID_IHTMLFramesCollection2, riid)) {
138         TRACE("(%p)->(IID_IHTMLFramesCollection2 %p)\n", This, ppv);
139         *ppv = HTMLWINDOW2(This);
140     }else if(IsEqualGUID(&IID_IHTMLWindow2, riid)) {
141         TRACE("(%p)->(IID_IHTMLWindow2 %p)\n", This, ppv);
142         *ppv = HTMLWINDOW2(This);
143     }else if(IsEqualGUID(&IID_IHTMLWindow3, riid)) {
144         TRACE("(%p)->(IID_IHTMLWindow3 %p)\n", This, ppv);
145         *ppv = HTMLWINDOW3(This);
146     }else if(IsEqualGUID(&IID_IHTMLWindow4, riid)) {
147         TRACE("(%p)->(IID_IHTMLWindow4 %p)\n", This, ppv);
148         *ppv = HTMLWINDOW4(This);
149     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
150         return *ppv ? S_OK : E_NOINTERFACE;
151     }
152
153     if(*ppv) {
154         IUnknown_AddRef((IUnknown*)*ppv);
155         return S_OK;
156     }
157
158     WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
159     return E_NOINTERFACE;
160 }
161
162 static ULONG WINAPI HTMLWindow2_AddRef(IHTMLWindow2 *iface)
163 {
164     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
165     LONG ref = InterlockedIncrement(&This->ref);
166
167     TRACE("(%p) ref=%d\n", This, ref);
168
169     return ref;
170 }
171
172 static ULONG WINAPI HTMLWindow2_Release(IHTMLWindow2 *iface)
173 {
174     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
175     LONG ref = InterlockedDecrement(&This->ref);
176
177     TRACE("(%p) ref=%d\n", This, ref);
178
179     if(!ref) {
180         DWORD i;
181
182         remove_target_tasks(This->task_magic);
183         set_window_bscallback(This, NULL);
184         set_current_mon(This, NULL);
185         window_set_docnode(This, NULL);
186         release_children(This);
187
188         if(This->frame_element)
189             This->frame_element->content_window = NULL;
190
191         if(This->option_factory) {
192             This->option_factory->window = NULL;
193             IHTMLOptionElementFactory_Release(HTMLOPTFACTORY(This->option_factory));
194         }
195
196         if(This->image_factory) {
197             This->image_factory->window = NULL;
198             IHTMLImageElementFactory_Release(HTMLIMGFACTORY(This->image_factory));
199         }
200
201         if(This->location) {
202             This->location->window = NULL;
203             IHTMLLocation_Release(HTMLLOCATION(This->location));
204         }
205
206         if(This->screen)
207             IHTMLScreen_Release(This->screen);
208
209         if(This->event_target)
210             release_event_target(This->event_target);
211         for(i=0; i < This->global_prop_cnt; i++)
212             heap_free(This->global_props[i].name);
213
214         This->window_ref->window = NULL;
215         windowref_release(This->window_ref);
216
217         heap_free(This->global_props);
218         release_script_hosts(This);
219
220         if(This->nswindow)
221             nsIDOMWindow_Release(This->nswindow);
222
223         list_remove(&This->entry);
224         release_dispex(&This->dispex);
225         heap_free(This);
226     }
227
228     return ref;
229 }
230
231 static HRESULT WINAPI HTMLWindow2_GetTypeInfoCount(IHTMLWindow2 *iface, UINT *pctinfo)
232 {
233     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
234
235     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(This), pctinfo);
236 }
237
238 static HRESULT WINAPI HTMLWindow2_GetTypeInfo(IHTMLWindow2 *iface, UINT iTInfo,
239                                               LCID lcid, ITypeInfo **ppTInfo)
240 {
241     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
242
243     return IDispatchEx_GetTypeInfo(DISPATCHEX(This), iTInfo, lcid, ppTInfo);
244 }
245
246 static HRESULT WINAPI HTMLWindow2_GetIDsOfNames(IHTMLWindow2 *iface, REFIID riid,
247                                                 LPOLESTR *rgszNames, UINT cNames,
248                                                 LCID lcid, DISPID *rgDispId)
249 {
250     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
251
252     return IDispatchEx_GetIDsOfNames(DISPATCHEX(This), riid, rgszNames, cNames, lcid, rgDispId);
253 }
254
255 static HRESULT WINAPI HTMLWindow2_Invoke(IHTMLWindow2 *iface, DISPID dispIdMember,
256                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
257                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
258 {
259     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
260
261     return IDispatchEx_Invoke(DISPATCHEX(This), dispIdMember, riid, lcid, wFlags, pDispParams,
262             pVarResult, pExcepInfo, puArgErr);
263 }
264
265 static HRESULT get_frame_by_index(nsIDOMWindowCollection *nsFrames, PRUint32 index, HTMLWindow **ret)
266 {
267     PRUint32 length;
268     nsIDOMWindow *nsWindow;
269     nsresult nsres;
270
271     nsres = nsIDOMWindowCollection_GetLength(nsFrames, &length);
272     if(NS_FAILED(nsres)) {
273         FIXME("nsIDOMWindowCollection_GetLength failed: 0x%08x\n", nsres);
274         return E_FAIL;
275     }
276
277     if(index >= length)
278         return DISP_E_MEMBERNOTFOUND;
279
280     nsres = nsIDOMWindowCollection_Item(nsFrames, index, &nsWindow);
281     if(NS_FAILED(nsres)) {
282         FIXME("nsIDOMWindowCollection_Item failed: 0x%08x\n", nsres);
283         return E_FAIL;
284     }
285
286     *ret = nswindow_to_window(nsWindow);
287
288     nsIDOMWindow_Release(nsWindow);
289
290     return S_OK;
291 }
292
293 static HRESULT WINAPI HTMLWindow2_item(IHTMLWindow2 *iface, VARIANT *pvarIndex, VARIANT *pvarResult)
294 {
295     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
296     nsIDOMWindowCollection *nsFrames;
297     HTMLWindow *window;
298     HRESULT hres;
299     nsresult nsres;
300
301     TRACE("(%p)->(%p %p)\n", This, pvarIndex, pvarResult);
302
303     nsres = nsIDOMWindow_GetFrames(This->nswindow, &nsFrames);
304     if(NS_FAILED(nsres)) {
305         FIXME("nsIDOMWindow_GetFrames failed: 0x%08x\n", nsres);
306         return E_FAIL;
307     }
308
309     if(V_VT(pvarIndex) == VT_I4) {
310         int index = V_I4(pvarIndex);
311         TRACE("Getting index %d\n", index);
312         if(index < 0) {
313             hres = DISP_E_MEMBERNOTFOUND;
314             goto cleanup;
315         }
316         hres = get_frame_by_index(nsFrames, index, &window);
317         if(FAILED(hres))
318             goto cleanup;
319     }else if(V_VT(pvarIndex) == VT_UINT) {
320         unsigned int index = V_UINT(pvarIndex);
321         TRACE("Getting index %u\n", index);
322         hres = get_frame_by_index(nsFrames, index, &window);
323         if(FAILED(hres))
324             goto cleanup;
325     }else if(V_VT(pvarIndex) == VT_BSTR) {
326         BSTR str = V_BSTR(pvarIndex);
327         PRUint32 length, i;
328
329         TRACE("Getting name %s\n", wine_dbgstr_w(str));
330
331         nsres = nsIDOMWindowCollection_GetLength(nsFrames, &length);
332
333         window = NULL;
334         for(i = 0; i < length && !window; ++i) {
335             HTMLWindow *cur_window;
336             nsIDOMWindow *nsWindow;
337             BSTR id;
338
339             nsres = nsIDOMWindowCollection_Item(nsFrames, i, &nsWindow);
340             if(NS_FAILED(nsres)) {
341                 FIXME("nsIDOMWindowCollection_Item failed: 0x%08x\n", nsres);
342                 hres = E_FAIL;
343                 goto cleanup;
344             }
345
346             cur_window = nswindow_to_window(nsWindow);
347
348             nsIDOMWindow_Release(nsWindow);
349
350             hres = IHTMLElement_get_id(HTMLELEM(&cur_window->frame_element->element), &id);
351             if(FAILED(hres)) {
352                 FIXME("IHTMLElement_get_id failed: 0x%08x\n", hres);
353                 goto cleanup;
354             }
355
356             if(!strcmpW(id, str))
357                 window = cur_window;
358
359             SysFreeString(id);
360         }
361
362         if(!window) {
363             hres = DISP_E_MEMBERNOTFOUND;
364             goto cleanup;
365         }
366     }else {
367         hres = E_INVALIDARG;
368         goto cleanup;
369     }
370
371     IHTMLWindow2_AddRef(HTMLWINDOW2(window));
372     V_VT(pvarResult) = VT_DISPATCH;
373     V_DISPATCH(pvarResult) = (IDispatch*)window;
374
375     hres = S_OK;
376
377 cleanup:
378     nsIDOMWindowCollection_Release(nsFrames);
379
380     return hres;
381 }
382
383 static HRESULT WINAPI HTMLWindow2_get_length(IHTMLWindow2 *iface, LONG *p)
384 {
385     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
386     nsIDOMWindowCollection *nscollection;
387     PRUint32 length;
388     nsresult nsres;
389
390     TRACE("(%p)->(%p)\n", This, p);
391
392     nsres = nsIDOMWindow_GetFrames(This->nswindow, &nscollection);
393     if(NS_FAILED(nsres)) {
394         ERR("GetFrames failed: %08x\n", nsres);
395         return E_FAIL;
396     }
397
398     nsres = nsIDOMWindowCollection_GetLength(nscollection, &length);
399     nsIDOMWindowCollection_Release(nscollection);
400     if(NS_FAILED(nsres)) {
401         ERR("GetLength failed: %08x\n", nsres);
402         return E_FAIL;
403     }
404
405     *p = length;
406     return S_OK;
407 }
408
409 static HRESULT WINAPI HTMLWindow2_get_frames(IHTMLWindow2 *iface, IHTMLFramesCollection2 **p)
410 {
411     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
412     FIXME("(%p)->(%p): semi-stub\n", This, p);
413
414     /* FIXME: Should return a separate Window object */
415     *p = (IHTMLFramesCollection2*)HTMLWINDOW2(This);
416     HTMLWindow2_AddRef(iface);
417     return S_OK;
418 }
419
420 static HRESULT WINAPI HTMLWindow2_put_defaultStatus(IHTMLWindow2 *iface, BSTR v)
421 {
422     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
423     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
424     return E_NOTIMPL;
425 }
426
427 static HRESULT WINAPI HTMLWindow2_get_defaultStatus(IHTMLWindow2 *iface, BSTR *p)
428 {
429     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
430     FIXME("(%p)->(%p)\n", This, p);
431     return E_NOTIMPL;
432 }
433
434 static HRESULT WINAPI HTMLWindow2_put_status(IHTMLWindow2 *iface, BSTR v)
435 {
436     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
437     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
438     return E_NOTIMPL;
439 }
440
441 static HRESULT WINAPI HTMLWindow2_get_status(IHTMLWindow2 *iface, BSTR *p)
442 {
443     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
444     FIXME("(%p)->(%p)\n", This, p);
445     return E_NOTIMPL;
446 }
447
448 static HRESULT WINAPI HTMLWindow2_setTimeout(IHTMLWindow2 *iface, BSTR expression,
449         LONG msec, VARIANT *language, LONG *timerID)
450 {
451     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
452     VARIANT expr_var;
453
454     TRACE("(%p)->(%s %d %p %p)\n", This, debugstr_w(expression), msec, language, timerID);
455
456     V_VT(&expr_var) = VT_BSTR;
457     V_BSTR(&expr_var) = expression;
458
459     return IHTMLWindow3_setTimeout(HTMLWINDOW3(This), &expr_var, msec, language, timerID);
460 }
461
462 static HRESULT WINAPI HTMLWindow2_clearTimeout(IHTMLWindow2 *iface, LONG timerID)
463 {
464     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
465
466     TRACE("(%p)->(%d)\n", This, timerID);
467
468     return clear_task_timer(&This->doc->basedoc, FALSE, timerID);
469 }
470
471 static HRESULT WINAPI HTMLWindow2_alert(IHTMLWindow2 *iface, BSTR message)
472 {
473     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
474     WCHAR wszTitle[100];
475
476     TRACE("(%p)->(%s)\n", This, debugstr_w(message));
477
478     if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle,
479                     sizeof(wszTitle)/sizeof(WCHAR))) {
480         WARN("Could not load message box title: %d\n", GetLastError());
481         return S_OK;
482     }
483
484     MessageBoxW(This->doc_obj->hwnd, message, wszTitle, MB_ICONWARNING);
485     return S_OK;
486 }
487
488 static HRESULT WINAPI HTMLWindow2_confirm(IHTMLWindow2 *iface, BSTR message,
489         VARIANT_BOOL *confirmed)
490 {
491     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
492     WCHAR wszTitle[100];
493
494     TRACE("(%p)->(%s %p)\n", This, debugstr_w(message), confirmed);
495
496     if(!confirmed) return E_INVALIDARG;
497
498     if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle,
499                 sizeof(wszTitle)/sizeof(WCHAR))) {
500         WARN("Could not load message box title: %d\n", GetLastError());
501         *confirmed = VARIANT_TRUE;
502         return S_OK;
503     }
504
505     if(MessageBoxW(This->doc_obj->hwnd, message, wszTitle,
506                 MB_OKCANCEL|MB_ICONQUESTION)==IDOK)
507         *confirmed = VARIANT_TRUE;
508     else *confirmed = VARIANT_FALSE;
509
510     return S_OK;
511 }
512
513 typedef struct
514 {
515     BSTR message;
516     BSTR dststr;
517     VARIANT *textdata;
518 }prompt_arg;
519
520 static INT_PTR CALLBACK prompt_dlgproc(HWND hwnd, UINT msg,
521         WPARAM wparam, LPARAM lparam)
522 {
523     switch(msg)
524     {
525         case WM_INITDIALOG:
526         {
527             prompt_arg *arg = (prompt_arg*)lparam;
528             WCHAR wszTitle[100];
529
530             if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle,
531                         sizeof(wszTitle)/sizeof(WCHAR))) {
532                 WARN("Could not load message box title: %d\n", GetLastError());
533                 EndDialog(hwnd, wparam);
534                 return FALSE;
535             }
536
537             SetWindowLongPtrW(hwnd, DWLP_USER, lparam);
538             SetWindowTextW(hwnd, wszTitle);
539             SetWindowTextW(GetDlgItem(hwnd, ID_PROMPT_PROMPT), arg->message);
540             SetWindowTextW(GetDlgItem(hwnd, ID_PROMPT_EDIT), arg->dststr);
541             return FALSE;
542         }
543         case WM_COMMAND:
544             switch(wparam)
545             {
546                 case MAKEWPARAM(IDCANCEL, BN_CLICKED):
547                     EndDialog(hwnd, wparam);
548                     return TRUE;
549                 case MAKEWPARAM(IDOK, BN_CLICKED):
550                 {
551                     prompt_arg *arg =
552                         (prompt_arg*)GetWindowLongPtrW(hwnd, DWLP_USER);
553                     HWND hwndPrompt = GetDlgItem(hwnd, ID_PROMPT_EDIT);
554                     INT len = GetWindowTextLengthW(hwndPrompt);
555
556                     if(!arg->textdata)
557                     {
558                         EndDialog(hwnd, wparam);
559                         return TRUE;
560                     }
561
562                     V_VT(arg->textdata) = VT_BSTR;
563                     if(!len && !arg->dststr)
564                         V_BSTR(arg->textdata) = NULL;
565                     else
566                     {
567                         V_BSTR(arg->textdata) = SysAllocStringLen(NULL, len);
568                         GetWindowTextW(hwndPrompt, V_BSTR(arg->textdata), len+1);
569                     }
570                     EndDialog(hwnd, wparam);
571                     return TRUE;
572                 }
573             }
574             return FALSE;
575         case WM_CLOSE:
576             EndDialog(hwnd, IDCANCEL);
577             return TRUE;
578         default:
579             return FALSE;
580     }
581 }
582
583 static HRESULT WINAPI HTMLWindow2_prompt(IHTMLWindow2 *iface, BSTR message,
584         BSTR dststr, VARIANT *textdata)
585 {
586     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
587     prompt_arg arg;
588
589     TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(message), debugstr_w(dststr), textdata);
590
591     if(textdata) V_VT(textdata) = VT_NULL;
592
593     arg.message = message;
594     arg.dststr = dststr;
595     arg.textdata = textdata;
596
597     DialogBoxParamW(hInst, MAKEINTRESOURCEW(ID_PROMPT_DIALOG),
598             This->doc_obj->hwnd, prompt_dlgproc, (LPARAM)&arg);
599     return S_OK;
600 }
601
602 static HRESULT WINAPI HTMLWindow2_get_Image(IHTMLWindow2 *iface, IHTMLImageElementFactory **p)
603 {
604     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
605
606     TRACE("(%p)->(%p)\n", This, p);
607
608     if(!This->image_factory)
609         This->image_factory = HTMLImageElementFactory_Create(This);
610
611     *p = HTMLIMGFACTORY(This->image_factory);
612     IHTMLImageElementFactory_AddRef(*p);
613
614     return S_OK;
615 }
616
617 static HRESULT WINAPI HTMLWindow2_get_location(IHTMLWindow2 *iface, IHTMLLocation **p)
618 {
619     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
620     HTMLLocation *location;
621     HRESULT hres;
622
623     TRACE("(%p)->(%p)\n", This, p);
624
625     hres = get_location(This, &location);
626     if(FAILED(hres))
627         return hres;
628
629     *p = HTMLLOCATION(location);
630     return S_OK;
631 }
632
633 static HRESULT WINAPI HTMLWindow2_get_history(IHTMLWindow2 *iface, IOmHistory **p)
634 {
635     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
636     FIXME("(%p)->(%p)\n", This, p);
637     return E_NOTIMPL;
638 }
639
640 static HRESULT WINAPI HTMLWindow2_close(IHTMLWindow2 *iface)
641 {
642     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
643     FIXME("(%p)->()\n", This);
644     return E_NOTIMPL;
645 }
646
647 static HRESULT WINAPI HTMLWindow2_put_opener(IHTMLWindow2 *iface, VARIANT v)
648 {
649     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
650     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
651     return E_NOTIMPL;
652 }
653
654 static HRESULT WINAPI HTMLWindow2_get_opener(IHTMLWindow2 *iface, VARIANT *p)
655 {
656     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
657     FIXME("(%p)->(%p)\n", This, p);
658     return E_NOTIMPL;
659 }
660
661 static HRESULT WINAPI HTMLWindow2_get_navigator(IHTMLWindow2 *iface, IOmNavigator **p)
662 {
663     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
664
665     TRACE("(%p)->(%p)\n", This, p);
666
667     *p = OmNavigator_Create();
668     return S_OK;
669 }
670
671 static HRESULT WINAPI HTMLWindow2_put_name(IHTMLWindow2 *iface, BSTR v)
672 {
673     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
674     nsAString name_str;
675     nsresult nsres;
676
677     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
678
679     nsAString_Init(&name_str, v);
680     nsres = nsIDOMWindow_SetName(This->nswindow, &name_str);
681     nsAString_Finish(&name_str);
682     if(NS_FAILED(nsres))
683         ERR("SetName failed: %08x\n", nsres);
684
685     return S_OK;
686 }
687
688 static HRESULT WINAPI HTMLWindow2_get_name(IHTMLWindow2 *iface, BSTR *p)
689 {
690     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
691     nsAString name_str;
692     nsresult nsres;
693     HRESULT hres;
694
695     TRACE("(%p)->(%p)\n", This, p);
696
697     nsAString_Init(&name_str, NULL);
698     nsres = nsIDOMWindow_GetName(This->nswindow, &name_str);
699     if(NS_SUCCEEDED(nsres)) {
700         const PRUnichar *name;
701
702         nsAString_GetData(&name_str, &name);
703         if(*name) {
704             *p = SysAllocString(name);
705             hres = *p ? S_OK : E_OUTOFMEMORY;
706         }else {
707             *p = NULL;
708             hres = S_OK;
709         }
710     }else {
711         ERR("GetName failed: %08x\n", nsres);
712         hres = E_FAIL;
713     }
714     nsAString_Finish(&name_str);
715
716     return hres;
717 }
718
719 static HRESULT WINAPI HTMLWindow2_get_parent(IHTMLWindow2 *iface, IHTMLWindow2 **p)
720 {
721     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
722     TRACE("(%p)->(%p)\n", This, p);
723
724     if(This->parent) {
725         *p = HTMLWINDOW2(This->parent);
726         IHTMLWindow2_AddRef(*p);
727     }else
728         *p = NULL;
729
730     return S_OK;
731 }
732
733 static HRESULT WINAPI HTMLWindow2_open(IHTMLWindow2 *iface, BSTR url, BSTR name,
734          BSTR features, VARIANT_BOOL replace, IHTMLWindow2 **pomWindowResult)
735 {
736     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
737     FIXME("(%p)->(%s %s %s %x %p)\n", This, debugstr_w(url), debugstr_w(name),
738           debugstr_w(features), replace, pomWindowResult);
739     return E_NOTIMPL;
740 }
741
742 static HRESULT WINAPI HTMLWindow2_get_self(IHTMLWindow2 *iface, IHTMLWindow2 **p)
743 {
744     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
745
746     TRACE("(%p)->(%p)\n", This, p);
747
748     /* FIXME: We should return kind of proxy window here. */
749     IHTMLWindow2_AddRef(HTMLWINDOW2(This));
750     *p = HTMLWINDOW2(This);
751     return S_OK;
752 }
753
754 static HRESULT WINAPI HTMLWindow2_get_top(IHTMLWindow2 *iface, IHTMLWindow2 **p)
755 {
756     HTMLWindow *This = HTMLWINDOW2_THIS(iface), *curr;
757     TRACE("(%p)->(%p)\n", This, p);
758
759     curr = This;
760     while(curr->parent)
761         curr = curr->parent;
762     *p = HTMLWINDOW2(curr);
763     IHTMLWindow2_AddRef(*p);
764
765     return S_OK;
766 }
767
768 static HRESULT WINAPI HTMLWindow2_get_window(IHTMLWindow2 *iface, IHTMLWindow2 **p)
769 {
770     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
771
772     TRACE("(%p)->(%p)\n", This, p);
773
774     /* FIXME: We should return kind of proxy window here. */
775     IHTMLWindow2_AddRef(HTMLWINDOW2(This));
776     *p = HTMLWINDOW2(This);
777     return S_OK;
778 }
779
780 static HRESULT WINAPI HTMLWindow2_navigate(IHTMLWindow2 *iface, BSTR url)
781 {
782     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
783     FIXME("(%p)->(%s)\n", This, debugstr_w(url));
784     return E_NOTIMPL;
785 }
786
787 static HRESULT WINAPI HTMLWindow2_put_onfocus(IHTMLWindow2 *iface, VARIANT v)
788 {
789     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
790     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
791     return E_NOTIMPL;
792 }
793
794 static HRESULT WINAPI HTMLWindow2_get_onfocus(IHTMLWindow2 *iface, VARIANT *p)
795 {
796     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
797     FIXME("(%p)->(%p)\n", This, p);
798     return E_NOTIMPL;
799 }
800
801 static HRESULT WINAPI HTMLWindow2_put_onblur(IHTMLWindow2 *iface, VARIANT v)
802 {
803     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
804     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
805     return E_NOTIMPL;
806 }
807
808 static HRESULT WINAPI HTMLWindow2_get_onblur(IHTMLWindow2 *iface, VARIANT *p)
809 {
810     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
811     FIXME("(%p)->(%p)\n", This, p);
812     return E_NOTIMPL;
813 }
814
815 static HRESULT WINAPI HTMLWindow2_put_onload(IHTMLWindow2 *iface, VARIANT v)
816 {
817     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
818
819     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
820
821     return set_window_event(This, EVENTID_LOAD, &v);
822 }
823
824 static HRESULT WINAPI HTMLWindow2_get_onload(IHTMLWindow2 *iface, VARIANT *p)
825 {
826     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
827
828     TRACE("(%p)->(%p)\n", This, p);
829
830     return get_window_event(This, EVENTID_LOAD, p);
831 }
832
833 static HRESULT WINAPI HTMLWindow2_put_onbeforeunload(IHTMLWindow2 *iface, VARIANT v)
834 {
835     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
836
837     TRACE("(%p)->(v(%d))\n", This, V_VT(&v));
838
839     return set_window_event(This, EVENTID_BEFOREUNLOAD, &v);
840 }
841
842 static HRESULT WINAPI HTMLWindow2_get_onbeforeunload(IHTMLWindow2 *iface, VARIANT *p)
843 {
844     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
845
846     TRACE("(%p)->(%p)\n", This, p);
847
848     return get_window_event(This, EVENTID_BEFOREUNLOAD, p);
849 }
850
851 static HRESULT WINAPI HTMLWindow2_put_onunload(IHTMLWindow2 *iface, VARIANT v)
852 {
853     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
854     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
855     return E_NOTIMPL;
856 }
857
858 static HRESULT WINAPI HTMLWindow2_get_onunload(IHTMLWindow2 *iface, VARIANT *p)
859 {
860     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
861     FIXME("(%p)->(%p)\n", This, p);
862     return E_NOTIMPL;
863 }
864
865 static HRESULT WINAPI HTMLWindow2_put_onhelp(IHTMLWindow2 *iface, VARIANT v)
866 {
867     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
868     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
869     return E_NOTIMPL;
870 }
871
872 static HRESULT WINAPI HTMLWindow2_get_onhelp(IHTMLWindow2 *iface, VARIANT *p)
873 {
874     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
875     FIXME("(%p)->(%p)\n", This, p);
876     return E_NOTIMPL;
877 }
878
879 static HRESULT WINAPI HTMLWindow2_put_onerror(IHTMLWindow2 *iface, VARIANT v)
880 {
881     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
882     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
883     return E_NOTIMPL;
884 }
885
886 static HRESULT WINAPI HTMLWindow2_get_onerror(IHTMLWindow2 *iface, VARIANT *p)
887 {
888     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
889     FIXME("(%p)->(%p)\n", This, p);
890     return E_NOTIMPL;
891 }
892
893 static HRESULT WINAPI HTMLWindow2_put_onresize(IHTMLWindow2 *iface, VARIANT v)
894 {
895     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
896
897     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
898
899     return set_window_event(This, EVENTID_RESIZE, &v);
900 }
901
902 static HRESULT WINAPI HTMLWindow2_get_onresize(IHTMLWindow2 *iface, VARIANT *p)
903 {
904     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
905
906     TRACE("(%p)->(%p)\n", This, p);
907
908     return get_window_event(This, EVENTID_RESIZE, p);
909 }
910
911 static HRESULT WINAPI HTMLWindow2_put_onscroll(IHTMLWindow2 *iface, VARIANT v)
912 {
913     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
914     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
915     return E_NOTIMPL;
916 }
917
918 static HRESULT WINAPI HTMLWindow2_get_onscroll(IHTMLWindow2 *iface, VARIANT *p)
919 {
920     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
921     FIXME("(%p)->(%p)\n", This, p);
922     return E_NOTIMPL;
923 }
924
925 static HRESULT WINAPI HTMLWindow2_get_document(IHTMLWindow2 *iface, IHTMLDocument2 **p)
926 {
927     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
928
929     TRACE("(%p)->(%p)\n", This, p);
930
931     if(This->doc) {
932         /* FIXME: We should return a wrapper object here */
933         *p = HTMLDOC(&This->doc->basedoc);
934         IHTMLDocument2_AddRef(*p);
935     }else {
936         *p = NULL;
937     }
938
939     return S_OK;
940 }
941
942 static HRESULT WINAPI HTMLWindow2_get_event(IHTMLWindow2 *iface, IHTMLEventObj **p)
943 {
944     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
945
946     TRACE("(%p)->(%p)\n", This, p);
947
948     if(This->event)
949         IHTMLEventObj_AddRef(This->event);
950     *p = This->event;
951     return S_OK;
952 }
953
954 static HRESULT WINAPI HTMLWindow2_get__newEnum(IHTMLWindow2 *iface, IUnknown **p)
955 {
956     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
957     FIXME("(%p)->(%p)\n", This, p);
958     return E_NOTIMPL;
959 }
960
961 static HRESULT WINAPI HTMLWindow2_showModalDialog(IHTMLWindow2 *iface, BSTR dialog,
962         VARIANT *varArgIn, VARIANT *varOptions, VARIANT *varArgOut)
963 {
964     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
965     FIXME("(%p)->(%s %p %p %p)\n", This, debugstr_w(dialog), varArgIn, varOptions, varArgOut);
966     return E_NOTIMPL;
967 }
968
969 static HRESULT WINAPI HTMLWindow2_showHelp(IHTMLWindow2 *iface, BSTR helpURL, VARIANT helpArg,
970         BSTR features)
971 {
972     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
973     FIXME("(%p)->(%s v(%d) %s)\n", This, debugstr_w(helpURL), V_VT(&helpArg), debugstr_w(features));
974     return E_NOTIMPL;
975 }
976
977 static HRESULT WINAPI HTMLWindow2_get_screen(IHTMLWindow2 *iface, IHTMLScreen **p)
978 {
979     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
980
981     TRACE("(%p)->(%p)\n", This, p);
982
983     if(!This->screen) {
984         HRESULT hres;
985
986         hres = HTMLScreen_Create(&This->screen);
987         if(FAILED(hres))
988             return hres;
989     }
990
991     *p = This->screen;
992     IHTMLScreen_AddRef(This->screen);
993     return S_OK;
994 }
995
996 static HRESULT WINAPI HTMLWindow2_get_Option(IHTMLWindow2 *iface, IHTMLOptionElementFactory **p)
997 {
998     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
999
1000     TRACE("(%p)->(%p)\n", This, p);
1001
1002     if(!This->option_factory)
1003         This->option_factory = HTMLOptionElementFactory_Create(This);
1004
1005     *p = HTMLOPTFACTORY(This->option_factory);
1006     IHTMLOptionElementFactory_AddRef(*p);
1007
1008     return S_OK;
1009 }
1010
1011 static HRESULT WINAPI HTMLWindow2_focus(IHTMLWindow2 *iface)
1012 {
1013     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1014     FIXME("(%p)->()\n", This);
1015     return E_NOTIMPL;
1016 }
1017
1018 static HRESULT WINAPI HTMLWindow2_get_closed(IHTMLWindow2 *iface, VARIANT_BOOL *p)
1019 {
1020     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1021     FIXME("(%p)->(%p)\n", This, p);
1022     return E_NOTIMPL;
1023 }
1024
1025 static HRESULT WINAPI HTMLWindow2_blur(IHTMLWindow2 *iface)
1026 {
1027     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1028     FIXME("(%p)->()\n", This);
1029     return E_NOTIMPL;
1030 }
1031
1032 static HRESULT WINAPI HTMLWindow2_scroll(IHTMLWindow2 *iface, LONG x, LONG y)
1033 {
1034     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1035     FIXME("(%p)->(%d %d)\n", This, x, y);
1036     return E_NOTIMPL;
1037 }
1038
1039 static HRESULT WINAPI HTMLWindow2_get_clientInformation(IHTMLWindow2 *iface, IOmNavigator **p)
1040 {
1041     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1042     FIXME("(%p)->(%p)\n", This, p);
1043     return E_NOTIMPL;
1044 }
1045
1046 static HRESULT WINAPI HTMLWindow2_setInterval(IHTMLWindow2 *iface, BSTR expression,
1047         LONG msec, VARIANT *language, LONG *timerID)
1048 {
1049     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1050     VARIANT expr;
1051
1052     TRACE("(%p)->(%s %d %p %p)\n", This, debugstr_w(expression), msec, language, timerID);
1053
1054     V_VT(&expr) = VT_BSTR;
1055     V_BSTR(&expr) = expression;
1056     return IHTMLWindow3_setInterval(HTMLWINDOW3(This), &expr, msec, language, timerID);
1057 }
1058
1059 static HRESULT WINAPI HTMLWindow2_clearInterval(IHTMLWindow2 *iface, LONG timerID)
1060 {
1061     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1062
1063     TRACE("(%p)->(%d)\n", This, timerID);
1064
1065     return clear_task_timer(&This->doc->basedoc, TRUE, timerID);
1066 }
1067
1068 static HRESULT WINAPI HTMLWindow2_put_offscreenBuffering(IHTMLWindow2 *iface, VARIANT v)
1069 {
1070     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1071     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
1072     return E_NOTIMPL;
1073 }
1074
1075 static HRESULT WINAPI HTMLWindow2_get_offscreenBuffering(IHTMLWindow2 *iface, VARIANT *p)
1076 {
1077     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1078     FIXME("(%p)->(%p)\n", This, p);
1079     return E_NOTIMPL;
1080 }
1081
1082 static HRESULT WINAPI HTMLWindow2_execScript(IHTMLWindow2 *iface, BSTR scode, BSTR language,
1083         VARIANT *pvarRet)
1084 {
1085     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1086     FIXME("(%p)->(%s %s %p)\n", This, debugstr_w(scode), debugstr_w(language), pvarRet);
1087     return E_NOTIMPL;
1088 }
1089
1090 static HRESULT WINAPI HTMLWindow2_toString(IHTMLWindow2 *iface, BSTR *String)
1091 {
1092     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1093
1094     static const WCHAR objectW[] = {'[','o','b','j','e','c','t',']',0};
1095
1096     TRACE("(%p)->(%p)\n", This, String);
1097
1098     if(!String)
1099         return E_INVALIDARG;
1100
1101     *String = SysAllocString(objectW);
1102     return *String ? S_OK : E_OUTOFMEMORY;
1103 }
1104
1105 static HRESULT WINAPI HTMLWindow2_scrollBy(IHTMLWindow2 *iface, LONG x, LONG y)
1106 {
1107     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1108     nsresult nsres;
1109
1110     TRACE("(%p)->(%d %d)\n", This, x, y);
1111
1112     nsres = nsIDOMWindow_ScrollBy(This->nswindow, x, y);
1113     if(NS_FAILED(nsres))
1114         ERR("ScrollBy failed: %08x\n", nsres);
1115
1116     return S_OK;
1117 }
1118
1119 static HRESULT WINAPI HTMLWindow2_scrollTo(IHTMLWindow2 *iface, LONG x, LONG y)
1120 {
1121     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1122     nsresult nsres;
1123
1124     TRACE("(%p)->(%d %d)\n", This, x, y);
1125
1126     nsres = nsIDOMWindow_ScrollTo(This->nswindow, x, y);
1127     if(NS_FAILED(nsres))
1128         ERR("ScrollTo failed: %08x\n", nsres);
1129
1130     return S_OK;
1131 }
1132
1133 static HRESULT WINAPI HTMLWindow2_moveTo(IHTMLWindow2 *iface, LONG x, LONG y)
1134 {
1135     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1136     FIXME("(%p)->(%d %d)\n", This, x, y);
1137     return E_NOTIMPL;
1138 }
1139
1140 static HRESULT WINAPI HTMLWindow2_moveBy(IHTMLWindow2 *iface, LONG x, LONG y)
1141 {
1142     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1143     FIXME("(%p)->(%d %d)\n", This, x, y);
1144     return E_NOTIMPL;
1145 }
1146
1147 static HRESULT WINAPI HTMLWindow2_resizeTo(IHTMLWindow2 *iface, LONG x, LONG y)
1148 {
1149     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1150     FIXME("(%p)->(%d %d)\n", This, x, y);
1151     return E_NOTIMPL;
1152 }
1153
1154 static HRESULT WINAPI HTMLWindow2_resizeBy(IHTMLWindow2 *iface, LONG x, LONG y)
1155 {
1156     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1157     FIXME("(%p)->(%d %d)\n", This, x, y);
1158     return E_NOTIMPL;
1159 }
1160
1161 static HRESULT WINAPI HTMLWindow2_get_external(IHTMLWindow2 *iface, IDispatch **p)
1162 {
1163     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1164
1165     TRACE("(%p)->(%p)\n", This, p);
1166
1167     *p = NULL;
1168
1169     if(!This->doc_obj->hostui)
1170         return S_OK;
1171
1172     return IDocHostUIHandler_GetExternal(This->doc_obj->hostui, p);
1173 }
1174
1175 static HRESULT HTMLWindow_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
1176         VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
1177 {
1178     HTMLWindow *This = HTMLWINDOW2_THIS(iface);
1179     global_prop_t *prop;
1180     DWORD idx;
1181     HRESULT hres;
1182
1183     idx = id - MSHTML_DISPID_CUSTOM_MIN;
1184     if(idx >= This->global_prop_cnt)
1185         return DISP_E_MEMBERNOTFOUND;
1186
1187     prop = This->global_props+idx;
1188
1189     switch(prop->type) {
1190     case GLOBAL_SCRIPTVAR: {
1191         IDispatchEx *dispex;
1192         IDispatch *disp;
1193
1194         disp = get_script_disp(prop->script_host);
1195         if(!disp)
1196             return E_UNEXPECTED;
1197
1198         hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
1199         if(SUCCEEDED(hres)) {
1200             TRACE("%s >>>\n", debugstr_w(prop->name));
1201             hres = IDispatchEx_InvokeEx(dispex, prop->id, lcid, flags, params, res, ei, caller);
1202             if(hres == S_OK)
1203                 TRACE("%s <<<\n", debugstr_w(prop->name));
1204             else
1205                 WARN("%s <<< %08x\n", debugstr_w(prop->name), hres);
1206             IDispatchEx_Release(dispex);
1207         }else {
1208             FIXME("No IDispatchEx\n");
1209         }
1210         IDispatch_Release(disp);
1211         break;
1212     }
1213     case GLOBAL_ELEMENTVAR: {
1214         IHTMLElement *elem;
1215
1216         hres = IHTMLDocument3_getElementById(HTMLDOC3(&This->doc->basedoc), prop->name, &elem);
1217         if(FAILED(hres))
1218             return hres;
1219
1220         if(!elem)
1221             return DISP_E_MEMBERNOTFOUND;
1222
1223         V_VT(res) = VT_DISPATCH;
1224         V_DISPATCH(res) = (IDispatch*)elem;
1225         break;
1226     }
1227     default:
1228         ERR("invalid type %d\n", prop->type);
1229         hres = DISP_E_MEMBERNOTFOUND;
1230     }
1231
1232     return hres;
1233 }
1234
1235 #undef HTMLWINDOW2_THIS
1236
1237 static const IHTMLWindow2Vtbl HTMLWindow2Vtbl = {
1238     HTMLWindow2_QueryInterface,
1239     HTMLWindow2_AddRef,
1240     HTMLWindow2_Release,
1241     HTMLWindow2_GetTypeInfoCount,
1242     HTMLWindow2_GetTypeInfo,
1243     HTMLWindow2_GetIDsOfNames,
1244     HTMLWindow2_Invoke,
1245     HTMLWindow2_item,
1246     HTMLWindow2_get_length,
1247     HTMLWindow2_get_frames,
1248     HTMLWindow2_put_defaultStatus,
1249     HTMLWindow2_get_defaultStatus,
1250     HTMLWindow2_put_status,
1251     HTMLWindow2_get_status,
1252     HTMLWindow2_setTimeout,
1253     HTMLWindow2_clearTimeout,
1254     HTMLWindow2_alert,
1255     HTMLWindow2_confirm,
1256     HTMLWindow2_prompt,
1257     HTMLWindow2_get_Image,
1258     HTMLWindow2_get_location,
1259     HTMLWindow2_get_history,
1260     HTMLWindow2_close,
1261     HTMLWindow2_put_opener,
1262     HTMLWindow2_get_opener,
1263     HTMLWindow2_get_navigator,
1264     HTMLWindow2_put_name,
1265     HTMLWindow2_get_name,
1266     HTMLWindow2_get_parent,
1267     HTMLWindow2_open,
1268     HTMLWindow2_get_self,
1269     HTMLWindow2_get_top,
1270     HTMLWindow2_get_window,
1271     HTMLWindow2_navigate,
1272     HTMLWindow2_put_onfocus,
1273     HTMLWindow2_get_onfocus,
1274     HTMLWindow2_put_onblur,
1275     HTMLWindow2_get_onblur,
1276     HTMLWindow2_put_onload,
1277     HTMLWindow2_get_onload,
1278     HTMLWindow2_put_onbeforeunload,
1279     HTMLWindow2_get_onbeforeunload,
1280     HTMLWindow2_put_onunload,
1281     HTMLWindow2_get_onunload,
1282     HTMLWindow2_put_onhelp,
1283     HTMLWindow2_get_onhelp,
1284     HTMLWindow2_put_onerror,
1285     HTMLWindow2_get_onerror,
1286     HTMLWindow2_put_onresize,
1287     HTMLWindow2_get_onresize,
1288     HTMLWindow2_put_onscroll,
1289     HTMLWindow2_get_onscroll,
1290     HTMLWindow2_get_document,
1291     HTMLWindow2_get_event,
1292     HTMLWindow2_get__newEnum,
1293     HTMLWindow2_showModalDialog,
1294     HTMLWindow2_showHelp,
1295     HTMLWindow2_get_screen,
1296     HTMLWindow2_get_Option,
1297     HTMLWindow2_focus,
1298     HTMLWindow2_get_closed,
1299     HTMLWindow2_blur,
1300     HTMLWindow2_scroll,
1301     HTMLWindow2_get_clientInformation,
1302     HTMLWindow2_setInterval,
1303     HTMLWindow2_clearInterval,
1304     HTMLWindow2_put_offscreenBuffering,
1305     HTMLWindow2_get_offscreenBuffering,
1306     HTMLWindow2_execScript,
1307     HTMLWindow2_toString,
1308     HTMLWindow2_scrollBy,
1309     HTMLWindow2_scrollTo,
1310     HTMLWindow2_moveTo,
1311     HTMLWindow2_moveBy,
1312     HTMLWindow2_resizeTo,
1313     HTMLWindow2_resizeBy,
1314     HTMLWindow2_get_external
1315 };
1316
1317 #define HTMLWINDOW3_THIS(iface) DEFINE_THIS(HTMLWindow, HTMLWindow3, iface)
1318
1319 static HRESULT WINAPI HTMLWindow3_QueryInterface(IHTMLWindow3 *iface, REFIID riid, void **ppv)
1320 {
1321     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1322
1323     return IHTMLWindow2_QueryInterface(HTMLWINDOW2(This), riid, ppv);
1324 }
1325
1326 static ULONG WINAPI HTMLWindow3_AddRef(IHTMLWindow3 *iface)
1327 {
1328     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1329
1330     return IHTMLWindow2_AddRef(HTMLWINDOW2(This));
1331 }
1332
1333 static ULONG WINAPI HTMLWindow3_Release(IHTMLWindow3 *iface)
1334 {
1335     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1336
1337     return IHTMLWindow2_Release(HTMLWINDOW2(This));
1338 }
1339
1340 static HRESULT WINAPI HTMLWindow3_GetTypeInfoCount(IHTMLWindow3 *iface, UINT *pctinfo)
1341 {
1342     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1343
1344     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(This), pctinfo);
1345 }
1346
1347 static HRESULT WINAPI HTMLWindow3_GetTypeInfo(IHTMLWindow3 *iface, UINT iTInfo,
1348                                               LCID lcid, ITypeInfo **ppTInfo)
1349 {
1350     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1351
1352     return IDispatchEx_GetTypeInfo(DISPATCHEX(This), iTInfo, lcid, ppTInfo);
1353 }
1354
1355 static HRESULT WINAPI HTMLWindow3_GetIDsOfNames(IHTMLWindow3 *iface, REFIID riid,
1356                                                 LPOLESTR *rgszNames, UINT cNames,
1357                                                 LCID lcid, DISPID *rgDispId)
1358 {
1359     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1360
1361     return IDispatchEx_GetIDsOfNames(DISPATCHEX(This), riid, rgszNames, cNames, lcid, rgDispId);
1362 }
1363
1364 static HRESULT WINAPI HTMLWindow3_Invoke(IHTMLWindow3 *iface, DISPID dispIdMember,
1365                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1366                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1367 {
1368     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1369
1370     return IDispatchEx_Invoke(DISPATCHEX(This), dispIdMember, riid, lcid, wFlags, pDispParams,
1371             pVarResult, pExcepInfo, puArgErr);
1372 }
1373
1374 static HRESULT WINAPI HTMLWindow3_get_screenLeft(IHTMLWindow3 *iface, LONG *p)
1375 {
1376     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1377     FIXME("(%p)->(%p)\n", This, p);
1378     return E_NOTIMPL;
1379 }
1380
1381 static HRESULT WINAPI HTMLWindow3_get_screenTop(IHTMLWindow3 *iface, LONG *p)
1382 {
1383     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1384     FIXME("(%p)->(%p)\n", This, p);
1385     return E_NOTIMPL;
1386 }
1387
1388 static HRESULT WINAPI HTMLWindow3_attachEvent(IHTMLWindow3 *iface, BSTR event, IDispatch *pDisp, VARIANT_BOOL *pfResult)
1389 {
1390     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1391
1392     TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(event), pDisp, pfResult);
1393
1394     return attach_event(&This->event_target, &This->doc_obj->basedoc, event, pDisp, pfResult);
1395 }
1396
1397 static HRESULT WINAPI HTMLWindow3_detachEvent(IHTMLWindow3 *iface, BSTR event, IDispatch *pDisp)
1398 {
1399     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1400     FIXME("(%p)->()\n", This);
1401     return E_NOTIMPL;
1402 }
1403
1404 static HRESULT window_set_timer(HTMLWindow *This, VARIANT *expr, LONG msec, VARIANT *language,
1405         BOOL interval, LONG *timer_id)
1406 {
1407     IDispatch *disp = NULL;
1408
1409     switch(V_VT(expr)) {
1410     case VT_DISPATCH:
1411         disp = V_DISPATCH(expr);
1412         IDispatch_AddRef(disp);
1413         break;
1414
1415     case VT_BSTR:
1416         disp = script_parse_event(This, V_BSTR(expr));
1417         break;
1418
1419     default:
1420         FIXME("unimplemented vt=%d\n", V_VT(expr));
1421         return E_NOTIMPL;
1422     }
1423
1424     if(!disp)
1425         return E_FAIL;
1426
1427     *timer_id = set_task_timer(&This->doc->basedoc, msec, interval, disp);
1428     IDispatch_Release(disp);
1429
1430     return S_OK;
1431 }
1432
1433 static HRESULT WINAPI HTMLWindow3_setTimeout(IHTMLWindow3 *iface, VARIANT *expression, LONG msec,
1434         VARIANT *language, LONG *timerID)
1435 {
1436     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1437
1438     TRACE("(%p)->(%p(%d) %d %p %p)\n", This, expression, V_VT(expression), msec, language, timerID);
1439
1440     return window_set_timer(This, expression, msec, language, FALSE, timerID);
1441 }
1442
1443 static HRESULT WINAPI HTMLWindow3_setInterval(IHTMLWindow3 *iface, VARIANT *expression, LONG msec,
1444         VARIANT *language, LONG *timerID)
1445 {
1446     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1447
1448     TRACE("(%p)->(%p %d %p %p)\n", This, expression, msec, language, timerID);
1449
1450     return window_set_timer(This, expression, msec, language, TRUE, timerID);
1451 }
1452
1453 static HRESULT WINAPI HTMLWindow3_print(IHTMLWindow3 *iface)
1454 {
1455     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1456     FIXME("(%p)\n", This);
1457     return E_NOTIMPL;
1458 }
1459
1460 static HRESULT WINAPI HTMLWindow3_put_onbeforeprint(IHTMLWindow3 *iface, VARIANT v)
1461 {
1462     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1463     FIXME("(%p)->()\n", This);
1464     return E_NOTIMPL;
1465 }
1466
1467 static HRESULT WINAPI HTMLWindow3_get_onbeforeprint(IHTMLWindow3 *iface, VARIANT *p)
1468 {
1469     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1470     FIXME("(%p)->(%p)\n", This, p);
1471     return E_NOTIMPL;
1472 }
1473
1474 static HRESULT WINAPI HTMLWindow3_put_onafterprint(IHTMLWindow3 *iface, VARIANT v)
1475 {
1476     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1477     FIXME("(%p)->()\n", This);
1478     return E_NOTIMPL;
1479 }
1480
1481 static HRESULT WINAPI HTMLWindow3_get_onafterprint(IHTMLWindow3 *iface, VARIANT *p)
1482 {
1483     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1484     FIXME("(%p)->(%p)\n", This, p);
1485     return E_NOTIMPL;
1486 }
1487
1488 static HRESULT WINAPI HTMLWindow3_get_clipboardData(IHTMLWindow3 *iface, IHTMLDataTransfer **p)
1489 {
1490     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1491     FIXME("(%p)->(%p)\n", This, p);
1492     return E_NOTIMPL;
1493 }
1494
1495 static HRESULT WINAPI HTMLWindow3_showModelessDialog(IHTMLWindow3 *iface, BSTR url,
1496         VARIANT *varArgIn, VARIANT *options, IHTMLWindow2 **pDialog)
1497 {
1498     HTMLWindow *This = HTMLWINDOW3_THIS(iface);
1499     FIXME("(%p)->(%s %p %p %p)\n", This, debugstr_w(url), varArgIn, options, pDialog);
1500     return E_NOTIMPL;
1501 }
1502
1503 #undef HTMLWINDOW3_THIS
1504
1505 static const IHTMLWindow3Vtbl HTMLWindow3Vtbl = {
1506     HTMLWindow3_QueryInterface,
1507     HTMLWindow3_AddRef,
1508     HTMLWindow3_Release,
1509     HTMLWindow3_GetTypeInfoCount,
1510     HTMLWindow3_GetTypeInfo,
1511     HTMLWindow3_GetIDsOfNames,
1512     HTMLWindow3_Invoke,
1513     HTMLWindow3_get_screenLeft,
1514     HTMLWindow3_get_screenTop,
1515     HTMLWindow3_attachEvent,
1516     HTMLWindow3_detachEvent,
1517     HTMLWindow3_setTimeout,
1518     HTMLWindow3_setInterval,
1519     HTMLWindow3_print,
1520     HTMLWindow3_put_onbeforeprint,
1521     HTMLWindow3_get_onbeforeprint,
1522     HTMLWindow3_put_onafterprint,
1523     HTMLWindow3_get_onafterprint,
1524     HTMLWindow3_get_clipboardData,
1525     HTMLWindow3_showModelessDialog
1526 };
1527
1528 #define HTMLWINDOW4_THIS(iface) DEFINE_THIS(HTMLWindow, HTMLWindow4, iface)
1529
1530 static HRESULT WINAPI HTMLWindow4_QueryInterface(IHTMLWindow4 *iface, REFIID riid, void **ppv)
1531 {
1532     HTMLWindow *This = HTMLWINDOW4_THIS(iface);
1533
1534     return IHTMLWindow2_QueryInterface(HTMLWINDOW2(This), riid, ppv);
1535 }
1536
1537 static ULONG WINAPI HTMLWindow4_AddRef(IHTMLWindow4 *iface)
1538 {
1539     HTMLWindow *This = HTMLWINDOW4_THIS(iface);
1540
1541     return IHTMLWindow2_AddRef(HTMLWINDOW2(This));
1542 }
1543
1544 static ULONG WINAPI HTMLWindow4_Release(IHTMLWindow4 *iface)
1545 {
1546     HTMLWindow *This = HTMLWINDOW4_THIS(iface);
1547
1548     return IHTMLWindow2_Release(HTMLWINDOW2(This));
1549 }
1550
1551 static HRESULT WINAPI HTMLWindow4_GetTypeInfoCount(IHTMLWindow4 *iface, UINT *pctinfo)
1552 {
1553     HTMLWindow *This = HTMLWINDOW4_THIS(iface);
1554
1555     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(This), pctinfo);
1556 }
1557
1558 static HRESULT WINAPI HTMLWindow4_GetTypeInfo(IHTMLWindow4 *iface, UINT iTInfo,
1559                                               LCID lcid, ITypeInfo **ppTInfo)
1560 {
1561     HTMLWindow *This = HTMLWINDOW4_THIS(iface);
1562
1563     return IDispatchEx_GetTypeInfo(DISPATCHEX(This), iTInfo, lcid, ppTInfo);
1564 }
1565
1566 static HRESULT WINAPI HTMLWindow4_GetIDsOfNames(IHTMLWindow4 *iface, REFIID riid,
1567                                                 LPOLESTR *rgszNames, UINT cNames,
1568                                                 LCID lcid, DISPID *rgDispId)
1569 {
1570     HTMLWindow *This = HTMLWINDOW4_THIS(iface);
1571
1572     return IDispatchEx_GetIDsOfNames(DISPATCHEX(This), riid, rgszNames, cNames, lcid, rgDispId);
1573 }
1574
1575 static HRESULT WINAPI HTMLWindow4_Invoke(IHTMLWindow4 *iface, DISPID dispIdMember,
1576                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1577                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1578 {
1579     HTMLWindow *This = HTMLWINDOW4_THIS(iface);
1580
1581     return IDispatchEx_Invoke(DISPATCHEX(This), dispIdMember, riid, lcid, wFlags, pDispParams,
1582             pVarResult, pExcepInfo, puArgErr);
1583 }
1584
1585 static HRESULT WINAPI HTMLWindow4_createPopup(IHTMLWindow4 *iface, VARIANT *varArgIn,
1586                             IDispatch **ppPopup)
1587 {
1588     HTMLWindow *This = HTMLWINDOW4_THIS(iface);
1589     FIXME("(%p)->(%p %p)\n", This, varArgIn, ppPopup);
1590     return E_NOTIMPL;
1591 }
1592
1593 static HRESULT WINAPI HTMLWindow4_get_frameElement(IHTMLWindow4 *iface, IHTMLFrameBase **p)
1594 {
1595     HTMLWindow *This = HTMLWINDOW4_THIS(iface);
1596     TRACE("(%p)->(%p)\n", This, p);
1597
1598     if(This->frame_element) {
1599         *p = HTMLFRAMEBASE(This->frame_element);
1600         IHTMLFrameBase_AddRef(*p);
1601     }else
1602         *p = NULL;
1603
1604     return S_OK;
1605 }
1606
1607 #undef HTMLWINDOW4_THIS
1608
1609 static const IHTMLWindow4Vtbl HTMLWindow4Vtbl = {
1610     HTMLWindow4_QueryInterface,
1611     HTMLWindow4_AddRef,
1612     HTMLWindow4_Release,
1613     HTMLWindow4_GetTypeInfoCount,
1614     HTMLWindow4_GetTypeInfo,
1615     HTMLWindow4_GetIDsOfNames,
1616     HTMLWindow4_Invoke,
1617     HTMLWindow4_createPopup,
1618     HTMLWindow4_get_frameElement
1619 };
1620
1621 #define DISPEX_THIS(iface) DEFINE_THIS(HTMLWindow, IDispatchEx, iface)
1622
1623 static HRESULT WINAPI WindowDispEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
1624 {
1625     HTMLWindow *This = DISPEX_THIS(iface);
1626
1627     return IHTMLWindow2_QueryInterface(HTMLWINDOW2(This), riid, ppv);
1628 }
1629
1630 static ULONG WINAPI WindowDispEx_AddRef(IDispatchEx *iface)
1631 {
1632     HTMLWindow *This = DISPEX_THIS(iface);
1633
1634     return IHTMLWindow2_AddRef(HTMLWINDOW2(This));
1635 }
1636
1637 static ULONG WINAPI WindowDispEx_Release(IDispatchEx *iface)
1638 {
1639     HTMLWindow *This = DISPEX_THIS(iface);
1640
1641     return IHTMLWindow2_Release(HTMLWINDOW2(This));
1642 }
1643
1644 static HRESULT WINAPI WindowDispEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
1645 {
1646     HTMLWindow *This = DISPEX_THIS(iface);
1647
1648     TRACE("(%p)->(%p)\n", This, pctinfo);
1649
1650     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo);
1651 }
1652
1653 static HRESULT WINAPI WindowDispEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
1654                                                LCID lcid, ITypeInfo **ppTInfo)
1655 {
1656     HTMLWindow *This = DISPEX_THIS(iface);
1657
1658     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1659
1660     return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo);
1661 }
1662
1663 static HRESULT WINAPI WindowDispEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
1664                                                  LPOLESTR *rgszNames, UINT cNames,
1665                                                  LCID lcid, DISPID *rgDispId)
1666 {
1667     HTMLWindow *This = DISPEX_THIS(iface);
1668
1669     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
1670           lcid, rgDispId);
1671
1672     /* FIXME: Use script dispatch */
1673
1674     return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId);
1675 }
1676
1677 static HRESULT WINAPI WindowDispEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
1678                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1679                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1680 {
1681     HTMLWindow *This = DISPEX_THIS(iface);
1682
1683     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1684           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1685
1686     /* FIXME: Use script dispatch */
1687
1688     return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid, wFlags, pDispParams,
1689                               pVarResult, pExcepInfo, puArgErr);
1690 }
1691
1692 static global_prop_t *alloc_global_prop(HTMLWindow *This, global_prop_type_t type, BSTR name)
1693 {
1694     if(This->global_prop_cnt == This->global_prop_size) {
1695         global_prop_t *new_props;
1696         DWORD new_size;
1697
1698         if(This->global_props) {
1699             new_size = This->global_prop_size*2;
1700             new_props = heap_realloc(This->global_props, new_size*sizeof(global_prop_t));
1701         }else {
1702             new_size = 16;
1703             new_props = heap_alloc(new_size*sizeof(global_prop_t));
1704         }
1705         if(!new_props)
1706             return NULL;
1707         This->global_props = new_props;
1708         This->global_prop_size = new_size;
1709     }
1710
1711     This->global_props[This->global_prop_cnt].name = heap_strdupW(name);
1712     if(!This->global_props[This->global_prop_cnt].name)
1713         return NULL;
1714
1715     This->global_props[This->global_prop_cnt].type = type;
1716     return This->global_props + This->global_prop_cnt++;
1717 }
1718
1719 static inline DWORD prop_to_dispid(HTMLWindow *This, global_prop_t *prop)
1720 {
1721     return MSHTML_DISPID_CUSTOM_MIN + (prop-This->global_props);
1722 }
1723
1724 HRESULT search_window_props(HTMLWindow *This, BSTR bstrName, DWORD grfdex, DISPID *pid)
1725 {
1726     DWORD i;
1727     ScriptHost *script_host;
1728     DISPID id;
1729
1730     for(i=0; i < This->global_prop_cnt; i++) {
1731         /* FIXME: case sensitivity */
1732         if(!strcmpW(This->global_props[i].name, bstrName)) {
1733             *pid = MSHTML_DISPID_CUSTOM_MIN+i;
1734             return S_OK;
1735         }
1736     }
1737
1738     if(find_global_prop(This, bstrName, grfdex, &script_host, &id)) {
1739         global_prop_t *prop;
1740
1741         prop = alloc_global_prop(This, GLOBAL_SCRIPTVAR, bstrName);
1742         if(!prop)
1743             return E_OUTOFMEMORY;
1744
1745         prop->script_host = script_host;
1746         prop->id = id;
1747
1748         *pid = prop_to_dispid(This, prop);
1749         return S_OK;
1750     }
1751
1752     return DISP_E_UNKNOWNNAME;
1753 }
1754
1755 static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
1756 {
1757     HTMLWindow *This = DISPEX_THIS(iface);
1758     HRESULT hres;
1759
1760     TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
1761
1762     hres = search_window_props(This, bstrName, grfdex, pid);
1763     if(hres != DISP_E_UNKNOWNNAME)
1764         return hres;
1765
1766     hres = IDispatchEx_GetDispID(DISPATCHEX(&This->dispex), bstrName, grfdex, pid);
1767     if(hres != DISP_E_UNKNOWNNAME)
1768         return hres;
1769
1770     if(This->doc) {
1771         global_prop_t *prop;
1772         IHTMLElement *elem;
1773
1774         hres = IHTMLDocument3_getElementById(HTMLDOC3(&This->doc->basedoc), bstrName, &elem);
1775         if(SUCCEEDED(hres) && elem) {
1776             IHTMLElement_Release(elem);
1777
1778             prop = alloc_global_prop(This, GLOBAL_ELEMENTVAR, bstrName);
1779             if(!prop)
1780                 return E_OUTOFMEMORY;
1781
1782             *pid = prop_to_dispid(This, prop);
1783             return S_OK;
1784         }
1785     }
1786
1787     return DISP_E_UNKNOWNNAME;
1788 }
1789
1790 static HRESULT WINAPI WindowDispEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1791         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
1792 {
1793     HTMLWindow *This = DISPEX_THIS(iface);
1794
1795     TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1796
1797     if(id == DISPID_IHTMLWINDOW2_LOCATION && (wFlags & DISPATCH_PROPERTYPUT)) {
1798         HTMLLocation *location;
1799         HRESULT hres;
1800
1801         TRACE("forwarding to location.href\n");
1802
1803         hres = get_location(This, &location);
1804         if(FAILED(hres))
1805             return hres;
1806
1807         hres = IDispatchEx_InvokeEx(DISPATCHEX(&location->dispex), DISPID_VALUE, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1808         IHTMLLocation_Release(HTMLLOCATION(location));
1809         return hres;
1810     }
1811
1812     return IDispatchEx_InvokeEx(DISPATCHEX(&This->dispex), id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1813 }
1814
1815 static HRESULT WINAPI WindowDispEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
1816 {
1817     HTMLWindow *This = DISPEX_THIS(iface);
1818
1819     TRACE("(%p)->(%s %x)\n", This, debugstr_w(bstrName), grfdex);
1820
1821     return IDispatchEx_DeleteMemberByName(DISPATCHEX(&This->dispex), bstrName, grfdex);
1822 }
1823
1824 static HRESULT WINAPI WindowDispEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
1825 {
1826     HTMLWindow *This = DISPEX_THIS(iface);
1827
1828     TRACE("(%p)->(%x)\n", This, id);
1829
1830     return IDispatchEx_DeleteMemberByDispID(DISPATCHEX(&This->dispex), id);
1831 }
1832
1833 static HRESULT WINAPI WindowDispEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
1834 {
1835     HTMLWindow *This = DISPEX_THIS(iface);
1836
1837     TRACE("(%p)->(%x %x %p)\n", This, id, grfdexFetch, pgrfdex);
1838
1839     return IDispatchEx_GetMemberProperties(DISPATCHEX(&This->dispex), id, grfdexFetch, pgrfdex);
1840 }
1841
1842 static HRESULT WINAPI WindowDispEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
1843 {
1844     HTMLWindow *This = DISPEX_THIS(iface);
1845
1846     TRACE("(%p)->(%x %p)\n", This, id, pbstrName);
1847
1848     return IDispatchEx_GetMemberName(DISPATCHEX(&This->dispex), id, pbstrName);
1849 }
1850
1851 static HRESULT WINAPI WindowDispEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
1852 {
1853     HTMLWindow *This = DISPEX_THIS(iface);
1854
1855     TRACE("(%p)->(%x %x %p)\n", This, grfdex, id, pid);
1856
1857     return IDispatchEx_GetNextDispID(DISPATCHEX(&This->dispex), grfdex, id, pid);
1858 }
1859
1860 static HRESULT WINAPI WindowDispEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
1861 {
1862     HTMLWindow *This = DISPEX_THIS(iface);
1863
1864     TRACE("(%p)->(%p)\n", This, ppunk);
1865
1866     *ppunk = NULL;
1867     return S_OK;
1868 }
1869
1870 #undef DISPEX_THIS
1871
1872 static const IDispatchExVtbl WindowDispExVtbl = {
1873     WindowDispEx_QueryInterface,
1874     WindowDispEx_AddRef,
1875     WindowDispEx_Release,
1876     WindowDispEx_GetTypeInfoCount,
1877     WindowDispEx_GetTypeInfo,
1878     WindowDispEx_GetIDsOfNames,
1879     WindowDispEx_Invoke,
1880     WindowDispEx_GetDispID,
1881     WindowDispEx_InvokeEx,
1882     WindowDispEx_DeleteMemberByName,
1883     WindowDispEx_DeleteMemberByDispID,
1884     WindowDispEx_GetMemberProperties,
1885     WindowDispEx_GetMemberName,
1886     WindowDispEx_GetNextDispID,
1887     WindowDispEx_GetNameSpaceParent
1888 };
1889
1890 static const tid_t HTMLWindow_iface_tids[] = {
1891     IHTMLWindow2_tid,
1892     IHTMLWindow3_tid,
1893     IHTMLWindow4_tid,
1894     0
1895 };
1896
1897 static const dispex_static_data_vtbl_t HTMLWindow_dispex_vtbl = {
1898     NULL,
1899     NULL,
1900     HTMLWindow_invoke
1901 };
1902
1903 static dispex_static_data_t HTMLWindow_dispex = {
1904     &HTMLWindow_dispex_vtbl,
1905     DispHTMLWindow2_tid,
1906     NULL,
1907     HTMLWindow_iface_tids
1908 };
1909
1910 HRESULT HTMLWindow_Create(HTMLDocumentObj *doc_obj, nsIDOMWindow *nswindow, HTMLWindow *parent, HTMLWindow **ret)
1911 {
1912     HTMLWindow *window;
1913
1914     window = heap_alloc_zero(sizeof(HTMLWindow));
1915     if(!window)
1916         return E_OUTOFMEMORY;
1917
1918     window->window_ref = heap_alloc(sizeof(windowref_t));
1919     if(!window->window_ref) {
1920         heap_free(window);
1921         return E_OUTOFMEMORY;
1922     }
1923
1924     window->lpHTMLWindow2Vtbl = &HTMLWindow2Vtbl;
1925     window->lpHTMLWindow3Vtbl = &HTMLWindow3Vtbl;
1926     window->lpHTMLWindow4Vtbl = &HTMLWindow4Vtbl;
1927     window->lpIDispatchExVtbl = &WindowDispExVtbl;
1928     window->ref = 1;
1929     window->doc_obj = doc_obj;
1930
1931     window->window_ref->window = window;
1932     window->window_ref->ref = 1;
1933
1934     init_dispex(&window->dispex, (IUnknown*)HTMLWINDOW2(window), &HTMLWindow_dispex);
1935
1936     if(nswindow) {
1937         nsIDOMWindow_AddRef(nswindow);
1938         window->nswindow = nswindow;
1939     }
1940
1941     window->scriptmode = parent ? parent->scriptmode : SCRIPTMODE_GECKO;
1942     window->readystate = READYSTATE_UNINITIALIZED;
1943     list_init(&window->script_hosts);
1944
1945     window->task_magic = get_task_target_magic();
1946     update_window_doc(window);
1947
1948     list_init(&window->children);
1949     list_add_head(&window_list, &window->entry);
1950
1951     if(parent) {
1952         IHTMLWindow2_AddRef(HTMLWINDOW2(window));
1953
1954         window->parent = parent;
1955         list_add_tail(&parent->children, &window->sibling_entry);
1956     }
1957
1958     *ret = window;
1959     return S_OK;
1960 }
1961
1962 void update_window_doc(HTMLWindow *window)
1963 {
1964     nsIDOMHTMLDocument *nshtmldoc;
1965     nsIDOMDocument *nsdoc;
1966     nsresult nsres;
1967
1968     nsres = nsIDOMWindow_GetDocument(window->nswindow, &nsdoc);
1969     if(NS_FAILED(nsres) || !nsdoc) {
1970         ERR("GetDocument failed: %08x\n", nsres);
1971         return;
1972     }
1973
1974     nsres = nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMHTMLDocument, (void**)&nshtmldoc);
1975     nsIDOMDocument_Release(nsdoc);
1976     if(NS_FAILED(nsres)) {
1977         ERR("Could not get nsIDOMHTMLDocument iface: %08x\n", nsres);
1978         return;
1979     }
1980
1981     if(!window->doc || window->doc->nsdoc != nshtmldoc) {
1982         HTMLDocumentNode *doc;
1983         HRESULT hres;
1984
1985         hres = create_doc_from_nsdoc(nshtmldoc, window->doc_obj, window, &doc);
1986         if(SUCCEEDED(hres)) {
1987             window_set_docnode(window, doc);
1988             htmldoc_release(&doc->basedoc);
1989         }else {
1990             ERR("create_doc_from_nsdoc failed: %08x\n", hres);
1991         }
1992     }
1993
1994     nsIDOMHTMLDocument_Release(nshtmldoc);
1995 }
1996
1997 HTMLWindow *nswindow_to_window(const nsIDOMWindow *nswindow)
1998 {
1999     HTMLWindow *iter;
2000
2001     LIST_FOR_EACH_ENTRY(iter, &window_list, HTMLWindow, entry) {
2002         if(iter->nswindow == nswindow)
2003             return iter;
2004     }
2005
2006     return NULL;
2007 }