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