2 * Copyright 2006-2007 Jacek Caban for CodeWeavers
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.
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.
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
19 #define NONAMELESSUNION
20 #define NONAMELESSSTRUCT
22 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(shdocvw
);
34 static const WCHAR emptyW
[] = {0};
37 const IBindStatusCallbackVtbl
*lpBindStatusCallbackVtbl
;
38 const IHttpNegotiateVtbl
*lpHttpNegotiateVtbl
;
50 #define BINDSC(x) ((IBindStatusCallback*) &(x)->lpBindStatusCallbackVtbl)
51 #define HTTPNEG(x) ((IHttpNegotiate*) &(x)->lpHttpNegotiateVtbl)
53 static void dump_BINDINFO(BINDINFO
*bi
)
55 static const char * const BINDINFOF_str
[] = {
57 "BINDINFOF_URLENCODESTGMEDDATA",
58 "BINDINFOF_URLENCODEDEXTRAINFO"
61 static const char * const BINDVERB_str
[] = {
81 bi
->cbSize
, debugstr_w(bi
->szExtraInfo
),
82 bi
->stgmedData
.tymed
, bi
->stgmedData
.u
.hGlobal
, bi
->stgmedData
.pUnkForRelease
,
83 bi
->grfBindInfoF
> BINDINFOF_URLENCODEDEXTRAINFO
84 ? "unknown" : BINDINFOF_str
[bi
->grfBindInfoF
],
85 bi
->dwBindVerb
> BINDVERB_CUSTOM
86 ? "unknown" : BINDVERB_str
[bi
->dwBindVerb
],
87 debugstr_w(bi
->szCustomVerb
),
88 bi
->cbstgmedData
, bi
->dwOptions
, bi
->dwOptionsFlags
, bi
->dwCodePage
,
89 bi
->securityAttributes
.nLength
,
90 bi
->securityAttributes
.lpSecurityDescriptor
,
91 bi
->securityAttributes
.bInheritHandle
,
92 debugstr_guid(&bi
->iid
),
93 bi
->pUnk
, bi
->dwReserved
97 static void set_status_text(BindStatusCallback
*This
, LPCWSTR str
)
100 DISPPARAMS dispparams
= {&arg
, NULL
, 1, 0};
105 V_VT(&arg
) = VT_BSTR
;
106 V_BSTR(&arg
) = str
? SysAllocString(str
) : NULL
;
107 call_sink(This
->doc_host
->cps
.wbe2
, DISPID_STATUSTEXTCHANGE
, &dispparams
);
110 if(This
->doc_host
->frame
)
111 IOleInPlaceFrame_SetStatusText(This
->doc_host
->frame
, str
);
114 static HRESULT
set_dochost_url(DocHost
*This
, const WCHAR
*url
)
119 new_url
= heap_strdupW(url
);
121 return E_OUTOFMEMORY
;
126 heap_free(This
->url
);
131 #define BINDSC_THIS(iface) DEFINE_THIS(BindStatusCallback, BindStatusCallback, iface)
133 static HRESULT WINAPI
BindStatusCallback_QueryInterface(IBindStatusCallback
*iface
,
134 REFIID riid
, void **ppv
)
136 BindStatusCallback
*This
= BINDSC_THIS(iface
);
140 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
141 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
143 }else if(IsEqualGUID(&IID_IBindStatusCallback
, riid
)) {
144 TRACE("(%p)->(IID_IBindStatusCallback %p)\n", This
, ppv
);
146 }else if(IsEqualGUID(&IID_IHttpNegotiate
, riid
)) {
147 TRACE("(%p)->(IID_IHttpNegotiate %p)\n", This
, ppv
);
148 *ppv
= HTTPNEG(This
);
152 IBindStatusCallback_AddRef(BINDSC(This
));
156 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
157 return E_NOINTERFACE
;
160 static ULONG WINAPI
BindStatusCallback_AddRef(IBindStatusCallback
*iface
)
162 BindStatusCallback
*This
= BINDSC_THIS(iface
);
163 LONG ref
= InterlockedIncrement(&This
->ref
);
165 TRACE("(%p) ref=%d\n", This
, ref
);
170 static ULONG WINAPI
BindStatusCallback_Release(IBindStatusCallback
*iface
)
172 BindStatusCallback
*This
= BINDSC_THIS(iface
);
173 LONG ref
= InterlockedDecrement(&This
->ref
);
175 TRACE("(%p) ref=%d\n", This
, ref
);
179 IOleClientSite_Release(CLIENTSITE(This
->doc_host
));
181 GlobalFree(This
->post_data
);
182 SysFreeString(This
->headers
);
183 heap_free(This
->url
);
190 static HRESULT WINAPI
BindStatusCallback_OnStartBinding(IBindStatusCallback
*iface
,
191 DWORD dwReserved
, IBinding
*pbind
)
193 BindStatusCallback
*This
= BINDSC_THIS(iface
);
195 TRACE("(%p)->(%d %p)\n", This
, dwReserved
, pbind
);
200 static HRESULT WINAPI
BindStatusCallback_GetPriority(IBindStatusCallback
*iface
,
203 BindStatusCallback
*This
= BINDSC_THIS(iface
);
204 FIXME("(%p)->(%p)\n", This
, pnPriority
);
208 static HRESULT WINAPI
BindStatusCallback_OnLowResource(IBindStatusCallback
*iface
,
211 BindStatusCallback
*This
= BINDSC_THIS(iface
);
212 FIXME("(%p)->(%d)\n", This
, reserved
);
216 static HRESULT WINAPI
BindStatusCallback_OnProgress(IBindStatusCallback
*iface
,
217 ULONG ulProgress
, ULONG ulProgressMax
, ULONG ulStatusCode
, LPCWSTR szStatusText
)
219 BindStatusCallback
*This
= BINDSC_THIS(iface
);
221 TRACE("(%p)->(%d %d %d %s)\n", This
, ulProgress
, ulProgressMax
, ulStatusCode
,
222 debugstr_w(szStatusText
));
224 switch(ulStatusCode
) {
225 case BINDSTATUS_REDIRECTING
:
226 return set_dochost_url(This
->doc_host
, szStatusText
);
227 case BINDSTATUS_BEGINDOWNLOADDATA
:
228 set_status_text(This
, szStatusText
); /* FIXME: "Start downloading from site: %s" */
230 case BINDSTATUS_ENDDOWNLOADDATA
:
231 set_status_text(This
, szStatusText
); /* FIXME: "Downloading from site: %s" */
233 case BINDSTATUS_CLASSIDAVAILABLE
:
234 case BINDSTATUS_MIMETYPEAVAILABLE
:
235 case BINDSTATUS_BEGINSYNCOPERATION
:
236 case BINDSTATUS_ENDSYNCOPERATION
:
239 FIXME("status code %u\n", ulStatusCode
);
245 static HRESULT WINAPI
BindStatusCallback_OnStopBinding(IBindStatusCallback
*iface
,
246 HRESULT hresult
, LPCWSTR szError
)
248 BindStatusCallback
*This
= BINDSC_THIS(iface
);
250 TRACE("(%p)->(%08x %s)\n", This
, hresult
, debugstr_w(szError
));
252 set_status_text(This
, emptyW
);
255 IOleClientSite_Release(CLIENTSITE(This
->doc_host
));
256 This
->doc_host
= NULL
;
262 static HRESULT WINAPI
BindStatusCallback_GetBindInfo(IBindStatusCallback
*iface
,
263 DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
265 BindStatusCallback
*This
= BINDSC_THIS(iface
);
267 TRACE("(%p)->(%p %p)\n", This
, grfBINDF
, pbindinfo
);
269 *grfBINDF
= BINDF_ASYNCHRONOUS
;
271 if(This
->post_data
) {
272 pbindinfo
->dwBindVerb
= BINDVERB_POST
;
274 pbindinfo
->stgmedData
.tymed
= TYMED_HGLOBAL
;
275 pbindinfo
->stgmedData
.u
.hGlobal
= This
->post_data
;
276 pbindinfo
->cbstgmedData
= This
->post_data_len
;
277 pbindinfo
->stgmedData
.pUnkForRelease
= (IUnknown
*)BINDSC(This
);
278 IBindStatusCallback_AddRef(BINDSC(This
));
284 static HRESULT WINAPI
BindStatusCallback_OnDataAvailable(IBindStatusCallback
*iface
,
285 DWORD grfBSCF
, DWORD dwSize
, FORMATETC
*pformatetc
, STGMEDIUM
*pstgmed
)
287 BindStatusCallback
*This
= BINDSC_THIS(iface
);
288 FIXME("(%p)->(%08x %d %p %p)\n", This
, grfBSCF
, dwSize
, pformatetc
, pstgmed
);
292 static HRESULT WINAPI
BindStatusCallback_OnObjectAvailable(IBindStatusCallback
*iface
,
293 REFIID riid
, IUnknown
*punk
)
295 BindStatusCallback
*This
= BINDSC_THIS(iface
);
297 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), punk
);
299 return dochost_object_available(This
->doc_host
, punk
);
304 static const IBindStatusCallbackVtbl BindStatusCallbackVtbl
= {
305 BindStatusCallback_QueryInterface
,
306 BindStatusCallback_AddRef
,
307 BindStatusCallback_Release
,
308 BindStatusCallback_OnStartBinding
,
309 BindStatusCallback_GetPriority
,
310 BindStatusCallback_OnLowResource
,
311 BindStatusCallback_OnProgress
,
312 BindStatusCallback_OnStopBinding
,
313 BindStatusCallback_GetBindInfo
,
314 BindStatusCallback_OnDataAvailable
,
315 BindStatusCallback_OnObjectAvailable
318 #define HTTPNEG_THIS(iface) DEFINE_THIS(BindStatusCallback, HttpNegotiate, iface)
320 static HRESULT WINAPI
HttpNegotiate_QueryInterface(IHttpNegotiate
*iface
,
321 REFIID riid
, void **ppv
)
323 BindStatusCallback
*This
= HTTPNEG_THIS(iface
);
324 return IBindStatusCallback_QueryInterface(BINDSC(This
), riid
, ppv
);
327 static ULONG WINAPI
HttpNegotiate_AddRef(IHttpNegotiate
*iface
)
329 BindStatusCallback
*This
= HTTPNEG_THIS(iface
);
330 return IBindStatusCallback_AddRef(BINDSC(This
));
333 static ULONG WINAPI
HttpNegotiate_Release(IHttpNegotiate
*iface
)
335 BindStatusCallback
*This
= HTTPNEG_THIS(iface
);
336 return IBindStatusCallback_Release(BINDSC(This
));
339 static HRESULT WINAPI
HttpNegotiate_BeginningTransaction(IHttpNegotiate
*iface
,
340 LPCWSTR szURL
, LPCWSTR szHeaders
, DWORD dwReserved
, LPWSTR
*pszAdditionalHeaders
)
342 BindStatusCallback
*This
= HTTPNEG_THIS(iface
);
344 TRACE("(%p)->(%s %s %d %p)\n", This
, debugstr_w(szURL
), debugstr_w(szHeaders
),
345 dwReserved
, pszAdditionalHeaders
);
348 int size
= (strlenW(This
->headers
)+1)*sizeof(WCHAR
);
349 *pszAdditionalHeaders
= CoTaskMemAlloc(size
);
350 memcpy(*pszAdditionalHeaders
, This
->headers
, size
);
356 static HRESULT WINAPI
HttpNegotiate_OnResponse(IHttpNegotiate
*iface
,
357 DWORD dwResponseCode
, LPCWSTR szResponseHeaders
, LPCWSTR szRequestHeaders
,
358 LPWSTR
*pszAdditionalRequestHeaders
)
360 BindStatusCallback
*This
= HTTPNEG_THIS(iface
);
361 TRACE("(%p)->(%d %s %s %p)\n", This
, dwResponseCode
, debugstr_w(szResponseHeaders
),
362 debugstr_w(szRequestHeaders
), pszAdditionalRequestHeaders
);
368 static const IHttpNegotiateVtbl HttpNegotiateVtbl
= {
369 HttpNegotiate_QueryInterface
,
370 HttpNegotiate_AddRef
,
371 HttpNegotiate_Release
,
372 HttpNegotiate_BeginningTransaction
,
373 HttpNegotiate_OnResponse
376 static BindStatusCallback
*create_callback(DocHost
*doc_host
, LPCWSTR url
, PBYTE post_data
,
377 ULONG post_data_len
, LPCWSTR headers
)
379 BindStatusCallback
*ret
= heap_alloc(sizeof(BindStatusCallback
));
381 ret
->lpBindStatusCallbackVtbl
= &BindStatusCallbackVtbl
;
382 ret
->lpHttpNegotiateVtbl
= &HttpNegotiateVtbl
;
385 ret
->url
= heap_strdupW(url
);
386 ret
->post_data
= NULL
;
387 ret
->post_data_len
= post_data_len
;
388 ret
->headers
= headers
? SysAllocString(headers
) : NULL
;
390 ret
->doc_host
= doc_host
;
391 IOleClientSite_AddRef(CLIENTSITE(doc_host
));
394 ret
->post_data
= GlobalAlloc(0, post_data_len
);
395 memcpy(ret
->post_data
, post_data
, post_data_len
);
401 static void on_before_navigate2(DocHost
*This
, LPCWSTR url
, SAFEARRAY
*post_data
, LPWSTR headers
, VARIANT_BOOL
*cancel
)
403 VARIANT var_url
, var_flags
, var_frame_name
, var_post_data
, var_post_data2
, var_headers
;
404 DISPPARAMS dispparams
;
405 VARIANTARG params
[7];
407 dispparams
.cArgs
= 7;
408 dispparams
.cNamedArgs
= 0;
409 dispparams
.rgdispidNamedArgs
= NULL
;
410 dispparams
.rgvarg
= params
;
412 This
->busy
= VARIANT_TRUE
;
414 V_VT(params
) = VT_BOOL
|VT_BYREF
;
415 V_BOOLREF(params
) = cancel
;
417 V_VT(params
+1) = (VT_BYREF
|VT_VARIANT
);
418 V_VARIANTREF(params
+1) = &var_headers
;
419 V_VT(&var_headers
) = VT_BSTR
;
420 V_BSTR(&var_headers
) = headers
;
422 V_VT(params
+2) = (VT_BYREF
|VT_VARIANT
);
423 V_VARIANTREF(params
+2) = &var_post_data2
;
424 V_VT(&var_post_data2
) = (VT_BYREF
|VT_VARIANT
);
425 V_VARIANTREF(&var_post_data2
) = &var_post_data
;
428 V_VT(&var_post_data
) = VT_UI1
|VT_ARRAY
;
429 V_ARRAY(&var_post_data
) = post_data
;
431 V_VT(&var_post_data
) = VT_EMPTY
;
434 V_VT(params
+3) = (VT_BYREF
|VT_VARIANT
);
435 V_VARIANTREF(params
+3) = &var_frame_name
;
436 V_VT(&var_frame_name
) = VT_BSTR
;
437 V_BSTR(&var_frame_name
) = NULL
;
439 V_VT(params
+4) = (VT_BYREF
|VT_VARIANT
);
440 V_VARIANTREF(params
+4) = &var_flags
;
441 V_VT(&var_flags
) = VT_I4
;
442 V_I4(&var_flags
) = 0;
444 V_VT(params
+5) = (VT_BYREF
|VT_VARIANT
);
445 V_VARIANTREF(params
+5) = &var_url
;
446 V_VT(&var_url
) = VT_BSTR
;
447 V_BSTR(&var_url
) = SysAllocString(url
);
449 V_VT(params
+6) = (VT_DISPATCH
);
450 V_DISPATCH(params
+6) = This
->disp
;
452 call_sink(This
->cps
.wbe2
, DISPID_BEFORENAVIGATE2
, &dispparams
);
454 SysFreeString(V_BSTR(&var_url
));
457 /* FIXME: urlmon should handle it */
458 static BOOL
try_application_url(LPCWSTR url
)
460 SHELLEXECUTEINFOW exec_info
;
466 static const WCHAR wszURLProtocol
[] = {'U','R','L',' ','P','r','o','t','o','c','o','l',0};
468 hres
= CoInternetParseUrl(url
, PARSE_SCHEMA
, 0, app
, sizeof(app
)/sizeof(WCHAR
), NULL
, 0);
472 res
= RegOpenKeyW(HKEY_CLASSES_ROOT
, app
, &hkey
);
473 if(res
!= ERROR_SUCCESS
)
476 res
= RegQueryValueExW(hkey
, wszURLProtocol
, NULL
, &type
, NULL
, NULL
);
478 if(res
!= ERROR_SUCCESS
|| type
!= REG_SZ
)
481 TRACE("openning application %s\n", debugstr_w(app
));
483 memset(&exec_info
, 0, sizeof(exec_info
));
484 exec_info
.cbSize
= sizeof(exec_info
);
485 exec_info
.lpFile
= url
;
486 exec_info
.nShow
= SW_SHOW
;
488 return ShellExecuteExW(&exec_info
);
491 static HRESULT
create_moniker(LPCWSTR url
, IMoniker
**mon
)
493 WCHAR new_url
[INTERNET_MAX_URL_LENGTH
];
498 return CreateURLMoniker(NULL
, url
, mon
);
501 size
= sizeof(new_url
);
502 hres
= UrlCreateFromPathW(url
, new_url
, &size
, 0);
504 WARN("UrlCreateFromPathW failed: %08x\n", hres
);
508 size
= sizeof(new_url
)/sizeof(WCHAR
);
509 hres
= UrlApplySchemeW(url
, new_url
, &size
, URL_APPLY_GUESSSCHEME
);
510 TRACE("got %s\n", debugstr_w(new_url
));
512 WARN("UrlApplyScheme failed: %08x\n", hres
);
517 return CreateURLMoniker(NULL
, new_url
, mon
);
520 static HRESULT
bind_to_object(DocHost
*This
, IMoniker
*mon
, LPCWSTR url
, IBindCtx
*bindctx
,
521 IBindStatusCallback
*callback
)
523 IUnknown
*unk
= NULL
;
528 IMoniker_AddRef(mon
);
530 hres
= create_moniker(url
, &mon
);
535 hres
= IMoniker_GetDisplayName(mon
, 0, NULL
, &display_name
);
537 FIXME("GetDisplayName failed: %08x\n", hres
);
541 hres
= set_dochost_url(This
, display_name
);
542 CoTaskMemFree(display_name
);
546 IBindCtx_RegisterObjectParam(bindctx
, (LPOLESTR
)SZ_HTML_CLIENTSITE_OBJECTPARAM
,
547 (IUnknown
*)CLIENTSITE(This
));
549 hres
= IMoniker_BindToObject(mon
, bindctx
, NULL
, &IID_IUnknown
, (void**)&unk
);
550 if(SUCCEEDED(hres
)) {
553 IUnknown_Release(unk
);
554 }else if(try_application_url(url
)) {
557 FIXME("BindToObject failed: %08x\n", hres
);
560 IMoniker_Release(mon
);
564 static void html_window_navigate(DocHost
*This
, IHTMLPrivateWindow
*window
, BSTR url
, BSTR headers
, SAFEARRAY
*post_data
)
566 VARIANT headers_var
, post_data_var
;
570 hres
= set_dochost_url(This
, url
);
574 empty_str
= SysAllocStringLen(NULL
, 0);
577 V_VT(&headers_var
) = VT_BSTR
;
578 V_BSTR(&headers_var
) = headers
;
580 V_VT(&headers_var
) = VT_EMPTY
;
584 V_VT(&post_data_var
) = VT_UI1
|VT_ARRAY
;
585 V_ARRAY(&post_data_var
) = post_data
;
587 V_VT(&post_data_var
) = VT_EMPTY
;
590 set_doc_state(This
, READYSTATE_LOADING
);
591 hres
= IHTMLPrivateWindow_SuperNavigate(window
, url
, empty_str
, NULL
, NULL
, &post_data_var
, &headers_var
, 0);
592 SysFreeString(empty_str
);
594 WARN("SuprtNavigate failed: %08x\n", hres
);
598 task_header_t header
;
601 SAFEARRAY
*post_data
;
603 } task_doc_navigate_t
;
605 static HRESULT
free_doc_navigate_task(task_doc_navigate_t
*task
, BOOL free_task
)
607 SysFreeString(task
->url
);
608 SysFreeString(task
->headers
);
610 SafeArrayDestroy(task
->post_data
);
613 return E_OUTOFMEMORY
;
616 static void doc_navigate_proc(DocHost
*This
, task_header_t
*t
)
618 task_doc_navigate_t
*task
= (task_doc_navigate_t
*)t
;
619 IHTMLPrivateWindow
*priv_window
;
622 if(!This
->doc_navigate
)
625 if(task
->async_notif
) {
626 VARIANT_BOOL cancel
= VARIANT_FALSE
;
627 on_before_navigate2(This
, task
->url
, task
->post_data
, task
->headers
, &cancel
);
629 TRACE("Navigation calnceled\n");
630 free_doc_navigate_task(task
, FALSE
);
635 hres
= IUnknown_QueryInterface(This
->doc_navigate
, &IID_IHTMLPrivateWindow
, (void**)&priv_window
);
636 if(SUCCEEDED(hres
)) {
637 html_window_navigate(This
, priv_window
, task
->url
, task
->headers
, task
->post_data
);
638 IHTMLPrivateWindow_Release(priv_window
);
640 WARN("Could not get IHTMLPrivateWindow iface: %08x\n", hres
);
643 free_doc_navigate_task(task
, FALSE
);
646 static HRESULT
async_doc_navigate(DocHost
*This
, LPCWSTR url
, LPCWSTR headers
, PBYTE post_data
, ULONG post_data_size
,
649 task_doc_navigate_t
*task
;
651 task
= heap_alloc_zero(sizeof(*task
));
653 return E_OUTOFMEMORY
;
655 task
->url
= SysAllocString(url
);
657 return free_doc_navigate_task(task
, TRUE
);
660 task
->headers
= SysAllocString(headers
);
662 return free_doc_navigate_task(task
, TRUE
);
666 task
->post_data
= SafeArrayCreateVector(VT_UI1
, 0, post_data_size
);
668 return free_doc_navigate_task(task
, TRUE
);
669 memcpy(task
->post_data
->pvData
, post_data
, post_data_size
);
673 VARIANT_BOOL cancel
= VARIANT_FALSE
;
675 on_before_navigate2(This
, task
->url
, task
->post_data
, task
->headers
, &cancel
);
677 TRACE("Navigation calnceled\n");
678 free_doc_navigate_task(task
, TRUE
);
683 task
->async_notif
= async_notif
;
684 push_dochost_task(This
, &task
->header
, doc_navigate_proc
, FALSE
);
688 static HRESULT
navigate_bsc(DocHost
*This
, BindStatusCallback
*bsc
, IMoniker
*mon
)
690 VARIANT_BOOL cancel
= VARIANT_FALSE
;
691 SAFEARRAY
*post_data
= NULL
;
695 set_doc_state(This
, READYSTATE_LOADING
);
698 post_data
= SafeArrayCreateVector(VT_UI1
, 0, bsc
->post_data_len
);
699 memcpy(post_data
->pvData
, post_data
, bsc
->post_data_len
);
702 on_before_navigate2(This
, bsc
->url
, post_data
, bsc
->headers
, &cancel
);
704 SafeArrayDestroy(post_data
);
706 FIXME("Navigation canceled\n");
711 deactivate_document(This
);
713 CreateAsyncBindCtx(0, BINDSC(bsc
), 0, &bindctx
);
716 IOleInPlaceFrame_EnableModeless(This
->frame
, FALSE
);
718 hres
= bind_to_object(This
, mon
, bsc
->url
, bindctx
, BINDSC(bsc
));
721 IOleInPlaceFrame_EnableModeless(This
->frame
, TRUE
);
723 IBindCtx_Release(bindctx
);
729 task_header_t header
;
730 BindStatusCallback
*bsc
;
731 } task_navigate_bsc_t
;
733 static void navigate_bsc_proc(DocHost
*This
, task_header_t
*t
)
735 task_navigate_bsc_t
*task
= (task_navigate_bsc_t
*)t
;
738 create_doc_view_hwnd(This
);
740 navigate_bsc(This
, task
->bsc
, NULL
);
742 IBindStatusCallback_Release(BINDSC(task
->bsc
));
746 HRESULT
navigate_url(DocHost
*This
, LPCWSTR url
, const VARIANT
*Flags
,
747 const VARIANT
*TargetFrameName
, VARIANT
*PostData
, VARIANT
*Headers
)
749 PBYTE post_data
= NULL
;
750 ULONG post_data_len
= 0;
751 LPWSTR headers
= NULL
;
754 TRACE("navigating to %s\n", debugstr_w(url
));
756 if((Flags
&& V_VT(Flags
) != VT_EMPTY
)
757 || (TargetFrameName
&& V_VT(TargetFrameName
) != VT_EMPTY
))
758 FIXME("Unsupported args (Flags %p:%d; TargetFrameName %p:%d)\n",
759 Flags
, Flags
? V_VT(Flags
) : -1, TargetFrameName
,
760 TargetFrameName
? V_VT(TargetFrameName
) : -1);
763 TRACE("PostData vt=%d\n", V_VT(PostData
));
765 if(V_VT(PostData
) == (VT_ARRAY
| VT_UI1
)) {
766 SafeArrayAccessData(V_ARRAY(PostData
), (void**)&post_data
);
767 post_data_len
= V_ARRAY(PostData
)->rgsabound
[0].cElements
;
771 if(Headers
&& V_VT(Headers
) != VT_EMPTY
&& V_VT(Headers
) != VT_ERROR
) {
772 if(V_VT(Headers
) != VT_BSTR
)
775 headers
= V_BSTR(Headers
);
776 TRACE("Headers: %s\n", debugstr_w(headers
));
779 set_doc_state(This
, READYSTATE_LOADING
);
780 This
->ready_state
= READYSTATE_LOADING
;
782 if(This
->doc_navigate
) {
783 WCHAR new_url
[INTERNET_MAX_URL_LENGTH
];
785 if(PathIsURLW(url
)) {
790 size
= sizeof(new_url
)/sizeof(WCHAR
);
791 hres
= UrlApplySchemeW(url
, new_url
, &size
, URL_APPLY_GUESSSCHEME
);
793 WARN("UrlApplyScheme failed: %08x\n", hres
);
798 hres
= async_doc_navigate(This
, *new_url
? new_url
: url
, headers
, post_data
,
799 post_data_len
, TRUE
);
801 task_navigate_bsc_t
*task
;
803 task
= heap_alloc(sizeof(*task
));
804 task
->bsc
= create_callback(This
, url
, post_data
, post_data_len
, headers
);
805 push_dochost_task(This
, &task
->header
, navigate_bsc_proc
, This
->url
== NULL
);
809 SafeArrayUnaccessData(V_ARRAY(PostData
));
814 static HRESULT
navigate_hlink(DocHost
*This
, IMoniker
*mon
, IBindCtx
*bindctx
,
815 IBindStatusCallback
*callback
)
817 IHttpNegotiate
*http_negotiate
;
818 BindStatusCallback
*bsc
;
819 PBYTE post_data
= NULL
;
820 ULONG post_data_len
= 0;
821 LPWSTR headers
= NULL
, url
;
826 hres
= IMoniker_GetDisplayName(mon
, 0, NULL
, &url
);
828 FIXME("GetDisplayName failed: %08x\n", hres
);
830 hres
= IBindStatusCallback_QueryInterface(callback
, &IID_IHttpNegotiate
,
831 (void**)&http_negotiate
);
832 if(SUCCEEDED(hres
)) {
833 static const WCHAR null_string
[] = {0};
835 IHttpNegotiate_BeginningTransaction(http_negotiate
, null_string
, null_string
, 0,
837 IHttpNegotiate_Release(http_negotiate
);
840 memset(&bindinfo
, 0, sizeof(bindinfo
));
841 bindinfo
.cbSize
= sizeof(bindinfo
);
843 hres
= IBindStatusCallback_GetBindInfo(callback
, &bindf
, &bindinfo
);
844 dump_BINDINFO(&bindinfo
);
845 if(bindinfo
.dwBindVerb
== BINDVERB_POST
) {
846 post_data_len
= bindinfo
.cbstgmedData
;
848 post_data
= bindinfo
.stgmedData
.u
.hGlobal
;
851 if(This
->doc_navigate
) {
852 hres
= async_doc_navigate(This
, url
, headers
, post_data
, post_data_len
, FALSE
);
854 bsc
= create_callback(This
, url
, post_data
, post_data_len
, headers
);
855 hres
= navigate_bsc(This
, bsc
, mon
);
856 IBindStatusCallback_Release(BINDSC(bsc
));
860 CoTaskMemFree(headers
);
861 ReleaseBindInfo(&bindinfo
);
866 HRESULT
go_home(DocHost
*This
)
869 DWORD res
, type
, size
;
870 WCHAR wszPageName
[MAX_PATH
];
871 static const WCHAR wszAboutBlank
[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
872 static const WCHAR wszStartPage
[] = {'S','t','a','r','t',' ','P','a','g','e',0};
873 static const WCHAR wszSubKey
[] = {'S','o','f','t','w','a','r','e','\\',
874 'M','i','c','r','o','s','o','f','t','\\',
875 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
878 res
= RegOpenKeyW(HKEY_CURRENT_USER
, wszSubKey
, &hkey
);
879 if (res
!= ERROR_SUCCESS
)
880 return navigate_url(This
, wszAboutBlank
, NULL
, NULL
, NULL
, NULL
);
882 size
= sizeof(wszPageName
);
883 res
= RegQueryValueExW(hkey
, wszStartPage
, NULL
, &type
, (LPBYTE
)wszPageName
, &size
);
885 if (res
!= ERROR_SUCCESS
|| type
!= REG_SZ
)
886 return navigate_url(This
, wszAboutBlank
, NULL
, NULL
, NULL
, NULL
);
888 return navigate_url(This
, wszPageName
, NULL
, NULL
, NULL
, NULL
);
891 static HRESULT
open_in_new_window(IMoniker
*mon
)
893 SHELLEXECUTEINFOW exec_info
;
897 static const WCHAR wszHtmlFile
[] = {'.','h','t','m','l',0};
899 hres
= IMoniker_GetDisplayName(mon
, NULL
, NULL
, &url
);
903 memset(&exec_info
, 0, sizeof(exec_info
));
904 exec_info
.cbSize
= sizeof(exec_info
);
905 exec_info
.fMask
= SEE_MASK_CLASSNAME
;
906 exec_info
.lpFile
= url
;
907 exec_info
.nShow
= SW_SHOW
;
908 exec_info
.lpClass
= wszHtmlFile
;
910 ShellExecuteExW(&exec_info
);
917 #define HLINKFRAME_THIS(iface) DEFINE_THIS(WebBrowser, HlinkFrame, iface)
919 static HRESULT WINAPI
HlinkFrame_QueryInterface(IHlinkFrame
*iface
, REFIID riid
, void **ppv
)
921 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
922 return IWebBrowser2_QueryInterface(WEBBROWSER2(This
), riid
, ppv
);
925 static ULONG WINAPI
HlinkFrame_AddRef(IHlinkFrame
*iface
)
927 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
928 return IWebBrowser2_AddRef(WEBBROWSER2(This
));
931 static ULONG WINAPI
HlinkFrame_Release(IHlinkFrame
*iface
)
933 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
934 return IWebBrowser2_Release(WEBBROWSER2(This
));
937 static HRESULT WINAPI
HlinkFrame_SetBrowseContext(IHlinkFrame
*iface
,
938 IHlinkBrowseContext
*pihlbc
)
940 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
941 FIXME("(%p)->(%p)\n", This
, pihlbc
);
945 static HRESULT WINAPI
HlinkFrame_GetBrowseContext(IHlinkFrame
*iface
,
946 IHlinkBrowseContext
**ppihlbc
)
948 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
949 FIXME("(%p)->(%p)\n", This
, ppihlbc
);
953 static HRESULT WINAPI
HlinkFrame_Navigate(IHlinkFrame
*iface
, DWORD grfHLNF
, LPBC pbc
,
954 IBindStatusCallback
*pibsc
, IHlink
*pihlNavigate
)
956 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
958 LPWSTR location
= NULL
;
960 TRACE("(%p)->(%08x %p %p %p)\n", This
, grfHLNF
, pbc
, pibsc
, pihlNavigate
);
963 FIXME("unsupported grfHLNF=%08x\n", grfHLNF
);
965 /* Windows calls GetTargetFrameName here. */
967 IHlink_GetMonikerReference(pihlNavigate
, 1, &mon
, &location
);
970 FIXME("location = %s\n", debugstr_w(location
));
971 CoTaskMemFree(location
);
974 /* Windows calls GetHlinkSite here */
976 if(grfHLNF
& HLNF_OPENINNEWWINDOW
) {
977 FIXME("Not supported HLNF_OPENINNEWWINDOW\n");
978 return open_in_new_window(mon
);
981 return navigate_hlink(&This
->doc_host
, mon
, pbc
, pibsc
);
984 static HRESULT WINAPI
HlinkFrame_OnNavigate(IHlinkFrame
*iface
, DWORD grfHLNF
,
985 IMoniker
*pimkTarget
, LPCWSTR pwzLocation
, LPCWSTR pwzFriendlyName
, DWORD dwreserved
)
987 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
988 FIXME("(%p)->(%08x %p %s %s %d)\n", This
, grfHLNF
, pimkTarget
, debugstr_w(pwzLocation
),
989 debugstr_w(pwzFriendlyName
), dwreserved
);
993 static HRESULT WINAPI
HlinkFrame_UpdateHlink(IHlinkFrame
*iface
, ULONG uHLID
,
994 IMoniker
*pimkTarget
, LPCWSTR pwzLocation
, LPCWSTR pwzFriendlyName
)
996 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
997 FIXME("(%p)->(%u %p %s %s)\n", This
, uHLID
, pimkTarget
, debugstr_w(pwzLocation
),
998 debugstr_w(pwzFriendlyName
));
1002 #undef HLINKFRAME_THIS
1004 static const IHlinkFrameVtbl HlinkFrameVtbl
= {
1005 HlinkFrame_QueryInterface
,
1008 HlinkFrame_SetBrowseContext
,
1009 HlinkFrame_GetBrowseContext
,
1010 HlinkFrame_Navigate
,
1011 HlinkFrame_OnNavigate
,
1012 HlinkFrame_UpdateHlink
1015 #define TARGETFRAME2_THIS(iface) DEFINE_THIS(WebBrowser, ITargetFrame2, iface)
1017 static HRESULT WINAPI
TargetFrame2_QueryInterface(ITargetFrame2
*iface
, REFIID riid
, void **ppv
)
1019 WebBrowser
*This
= TARGETFRAME2_THIS(iface
);
1020 return IWebBrowser2_QueryInterface(WEBBROWSER2(This
), riid
, ppv
);
1023 static ULONG WINAPI
TargetFrame2_AddRef(ITargetFrame2
*iface
)
1025 WebBrowser
*This
= TARGETFRAME2_THIS(iface
);
1026 return IWebBrowser2_AddRef(WEBBROWSER2(This
));
1029 static ULONG WINAPI
TargetFrame2_Release(ITargetFrame2
*iface
)
1031 WebBrowser
*This
= TARGETFRAME2_THIS(iface
);
1032 return IWebBrowser2_Release(WEBBROWSER2(This
));
1035 static HRESULT WINAPI
TargetFrame2_SetFrameName(ITargetFrame2
*iface
, LPCWSTR pszFrameName
)
1037 WebBrowser
*This
= TARGETFRAME2_THIS(iface
);
1038 FIXME("(%p)->(%s)\n", This
, debugstr_w(pszFrameName
));
1042 static HRESULT WINAPI
TargetFrame2_GetFrameName(ITargetFrame2
*iface
, LPWSTR
*ppszFrameName
)
1044 WebBrowser
*This
= TARGETFRAME2_THIS(iface
);
1045 FIXME("(%p)->(%p)\n", This
, ppszFrameName
);
1049 static HRESULT WINAPI
TargetFrame2_GetParentFrame(ITargetFrame2
*iface
, IUnknown
**ppunkParent
)
1051 WebBrowser
*This
= TARGETFRAME2_THIS(iface
);
1052 FIXME("(%p)->(%p)\n", This
, ppunkParent
);
1056 static HRESULT WINAPI
TargetFrame2_SetFrameSrc(ITargetFrame2
*iface
, LPCWSTR pszFrameSrc
)
1058 WebBrowser
*This
= TARGETFRAME2_THIS(iface
);
1059 FIXME("(%p)->(%s)\n", This
, debugstr_w(pszFrameSrc
));
1063 static HRESULT WINAPI
TargetFrame2_GetFrameSrc(ITargetFrame2
*iface
, LPWSTR
*ppszFrameSrc
)
1065 WebBrowser
*This
= TARGETFRAME2_THIS(iface
);
1066 FIXME("(%p)->()\n", This
);
1070 static HRESULT WINAPI
TargetFrame2_GetFramesContainer(ITargetFrame2
*iface
, IOleContainer
**ppContainer
)
1072 WebBrowser
*This
= TARGETFRAME2_THIS(iface
);
1073 FIXME("(%p)->(%p)\n", This
, ppContainer
);
1077 static HRESULT WINAPI
TargetFrame2_SetFrameOptions(ITargetFrame2
*iface
, DWORD dwFlags
)
1079 WebBrowser
*This
= TARGETFRAME2_THIS(iface
);
1080 FIXME("(%p)->(%x)\n", This
, dwFlags
);
1084 static HRESULT WINAPI
TargetFrame2_GetFrameOptions(ITargetFrame2
*iface
, DWORD
*pdwFlags
)
1086 WebBrowser
*This
= TARGETFRAME2_THIS(iface
);
1087 FIXME("(%p)->(%p)\n", This
, pdwFlags
);
1091 static HRESULT WINAPI
TargetFrame2_SetFrameMargins(ITargetFrame2
*iface
, DWORD dwWidth
, DWORD dwHeight
)
1093 WebBrowser
*This
= TARGETFRAME2_THIS(iface
);
1094 FIXME("(%p)->(%d %d)\n", This
, dwWidth
, dwHeight
);
1098 static HRESULT WINAPI
TargetFrame2_GetFrameMargins(ITargetFrame2
*iface
, DWORD
*pdwWidth
, DWORD
*pdwHeight
)
1100 WebBrowser
*This
= TARGETFRAME2_THIS(iface
);
1101 FIXME("(%p)->(%p %p)\n", This
, pdwWidth
, pdwHeight
);
1105 static HRESULT WINAPI
TargetFrame2_FindFrame(ITargetFrame2
*iface
, LPCWSTR pszTargetName
, DWORD dwFlags
, IUnknown
**ppunkTargetFrame
)
1107 WebBrowser
*This
= TARGETFRAME2_THIS(iface
);
1108 FIXME("(%p)->(%s %x %p)\n", This
, debugstr_w(pszTargetName
), dwFlags
, ppunkTargetFrame
);
1112 static HRESULT WINAPI
TargetFrame2_GetTargetAlias(ITargetFrame2
*iface
, LPCWSTR pszTargetName
, LPWSTR
*ppszTargetAlias
)
1114 WebBrowser
*This
= TARGETFRAME2_THIS(iface
);
1115 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(pszTargetName
), ppszTargetAlias
);
1119 #undef TARGETFRAME2_THIS
1121 static const ITargetFrame2Vtbl TargetFrame2Vtbl
= {
1122 TargetFrame2_QueryInterface
,
1123 TargetFrame2_AddRef
,
1124 TargetFrame2_Release
,
1125 TargetFrame2_SetFrameName
,
1126 TargetFrame2_GetFrameName
,
1127 TargetFrame2_GetParentFrame
,
1128 TargetFrame2_SetFrameSrc
,
1129 TargetFrame2_GetFrameSrc
,
1130 TargetFrame2_GetFramesContainer
,
1131 TargetFrame2_SetFrameOptions
,
1132 TargetFrame2_GetFrameOptions
,
1133 TargetFrame2_SetFrameMargins
,
1134 TargetFrame2_GetFrameMargins
,
1135 TargetFrame2_FindFrame
,
1136 TargetFrame2_GetTargetAlias
1139 void WebBrowser_HlinkFrame_Init(WebBrowser
*This
)
1141 This
->lpHlinkFrameVtbl
= &HlinkFrameVtbl
;
1142 This
->lpITargetFrame2Vtbl
= &TargetFrame2Vtbl
;