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 IBindStatusCallback IBindStatusCallback_iface
;
38 IHttpNegotiate IHttpNegotiate_iface
;
51 static void dump_BINDINFO(BINDINFO
*bi
)
53 static const char * const BINDINFOF_str
[] = {
55 "BINDINFOF_URLENCODESTGMEDDATA",
56 "BINDINFOF_URLENCODEDEXTRAINFO"
59 static const char * const BINDVERB_str
[] = {
79 bi
->cbSize
, debugstr_w(bi
->szExtraInfo
),
80 bi
->stgmedData
.tymed
, bi
->stgmedData
.u
.hGlobal
, bi
->stgmedData
.pUnkForRelease
,
81 bi
->grfBindInfoF
> BINDINFOF_URLENCODEDEXTRAINFO
82 ? "unknown" : BINDINFOF_str
[bi
->grfBindInfoF
],
83 bi
->dwBindVerb
> BINDVERB_CUSTOM
84 ? "unknown" : BINDVERB_str
[bi
->dwBindVerb
],
85 debugstr_w(bi
->szCustomVerb
),
86 bi
->cbstgmedData
, bi
->dwOptions
, bi
->dwOptionsFlags
, bi
->dwCodePage
,
87 bi
->securityAttributes
.nLength
,
88 bi
->securityAttributes
.lpSecurityDescriptor
,
89 bi
->securityAttributes
.bInheritHandle
,
90 debugstr_guid(&bi
->iid
),
91 bi
->pUnk
, bi
->dwReserved
95 static void set_status_text(BindStatusCallback
*This
, LPCWSTR str
)
98 DISPPARAMS dispparams
= {&arg
, NULL
, 1, 0};
103 V_VT(&arg
) = VT_BSTR
;
104 V_BSTR(&arg
) = str
? SysAllocString(str
) : NULL
;
105 call_sink(This
->doc_host
->cps
.wbe2
, DISPID_STATUSTEXTCHANGE
, &dispparams
);
108 if(This
->doc_host
->frame
)
109 IOleInPlaceFrame_SetStatusText(This
->doc_host
->frame
, str
);
112 static HRESULT
set_dochost_url(DocHost
*This
, const WCHAR
*url
)
117 new_url
= heap_strdupW(url
);
119 return E_OUTOFMEMORY
;
124 heap_free(This
->url
);
127 This
->container_vtbl
->SetURL(This
, This
->url
);
131 static inline BindStatusCallback
*impl_from_IBindStatusCallback(IBindStatusCallback
*iface
)
133 return CONTAINING_RECORD(iface
, BindStatusCallback
, IBindStatusCallback_iface
);
136 static HRESULT WINAPI
BindStatusCallback_QueryInterface(IBindStatusCallback
*iface
,
137 REFIID riid
, void **ppv
)
139 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
141 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
142 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
143 *ppv
= &This
->IBindStatusCallback_iface
;
144 }else if(IsEqualGUID(&IID_IBindStatusCallback
, riid
)) {
145 TRACE("(%p)->(IID_IBindStatusCallback %p)\n", This
, ppv
);
146 *ppv
= &This
->IBindStatusCallback_iface
;
147 }else if(IsEqualGUID(&IID_IHttpNegotiate
, riid
)) {
148 TRACE("(%p)->(IID_IHttpNegotiate %p)\n", This
, ppv
);
149 *ppv
= &This
->IHttpNegotiate_iface
;
152 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
153 return E_NOINTERFACE
;
156 IUnknown_AddRef((IUnknown
*)*ppv
);
160 static ULONG WINAPI
BindStatusCallback_AddRef(IBindStatusCallback
*iface
)
162 BindStatusCallback
*This
= impl_from_IBindStatusCallback(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
= impl_from_IBindStatusCallback(iface
);
173 LONG ref
= InterlockedDecrement(&This
->ref
);
175 TRACE("(%p) ref=%d\n", This
, ref
);
179 IOleClientSite_Release(&This
->doc_host
->IOleClientSite_iface
);
181 IBinding_Release(This
->binding
);
183 GlobalFree(This
->post_data
);
184 SysFreeString(This
->headers
);
185 heap_free(This
->url
);
192 static HRESULT WINAPI
BindStatusCallback_OnStartBinding(IBindStatusCallback
*iface
,
193 DWORD dwReserved
, IBinding
*pbind
)
195 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
197 TRACE("(%p)->(%d %p)\n", This
, dwReserved
, pbind
);
199 This
->binding
= pbind
;
200 IBinding_AddRef(This
->binding
);
205 static HRESULT WINAPI
BindStatusCallback_GetPriority(IBindStatusCallback
*iface
,
208 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
209 FIXME("(%p)->(%p)\n", This
, pnPriority
);
213 static HRESULT WINAPI
BindStatusCallback_OnLowResource(IBindStatusCallback
*iface
,
216 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
217 FIXME("(%p)->(%d)\n", This
, reserved
);
221 static DWORD
get_http_status_code(IBinding
*binding
)
223 IWinInetHttpInfo
*http_info
;
224 DWORD status
, size
= sizeof(DWORD
);
227 hres
= IBinding_QueryInterface(binding
, &IID_IWinInetHttpInfo
, (void**)&http_info
);
229 return HTTP_STATUS_OK
;
231 hres
= IWinInetHttpInfo_QueryInfo(http_info
, HTTP_QUERY_STATUS_CODE
|HTTP_QUERY_FLAG_NUMBER
,
232 &status
, &size
, NULL
, NULL
);
233 IWinInetHttpInfo_Release(http_info
);
236 return HTTP_STATUS_OK
;
240 static HRESULT WINAPI
BindStatusCallback_OnProgress(IBindStatusCallback
*iface
,
241 ULONG ulProgress
, ULONG ulProgressMax
, ULONG ulStatusCode
, LPCWSTR szStatusText
)
243 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
246 TRACE("(%p)->(%d %d %d %s)\n", This
, ulProgress
, ulProgressMax
, ulStatusCode
,
247 debugstr_w(szStatusText
));
249 switch(ulStatusCode
) {
250 case BINDSTATUS_REDIRECTING
:
251 return set_dochost_url(This
->doc_host
, szStatusText
);
252 case BINDSTATUS_BEGINDOWNLOADDATA
:
253 set_status_text(This
, szStatusText
); /* FIXME: "Start downloading from site: %s" */
254 status_code
= get_http_status_code(This
->binding
);
255 if(status_code
!= HTTP_STATUS_OK
)
256 handle_navigation_error(This
->doc_host
, status_code
, This
->url
, NULL
);
258 case BINDSTATUS_ENDDOWNLOADDATA
:
259 set_status_text(This
, szStatusText
); /* FIXME: "Downloading from site: %s" */
261 case BINDSTATUS_CLASSIDAVAILABLE
:
262 case BINDSTATUS_MIMETYPEAVAILABLE
:
263 case BINDSTATUS_BEGINSYNCOPERATION
:
264 case BINDSTATUS_ENDSYNCOPERATION
:
267 FIXME("status code %u\n", ulStatusCode
);
273 void handle_navigation_error(DocHost
* doc_host
, HRESULT hres
, BSTR url
, IHTMLWindow2
*win2
)
275 VARIANT var_status_code
, var_frame_name
, var_url
;
276 DISPPARAMS dispparams
;
277 VARIANTARG params
[5];
278 VARIANT_BOOL cancel
= VARIANT_FALSE
;
280 dispparams
.cArgs
= 5;
281 dispparams
.cNamedArgs
= 0;
282 dispparams
.rgdispidNamedArgs
= NULL
;
283 dispparams
.rgvarg
= params
;
285 V_VT(params
) = VT_BOOL
|VT_BYREF
;
286 V_BOOLREF(params
) = &cancel
;
288 V_VT(params
+1) = VT_VARIANT
|VT_BYREF
;
289 V_VARIANTREF(params
+1) = &var_status_code
;
290 V_VT(&var_status_code
) = VT_I4
;
291 V_I4(&var_status_code
) = hres
;
293 V_VT(params
+2) = VT_VARIANT
|VT_BYREF
;
294 V_VARIANTREF(params
+2) = &var_frame_name
;
295 V_VT(&var_frame_name
) = VT_BSTR
;
297 hres
= IHTMLWindow2_get_name(win2
, &V_BSTR(&var_frame_name
));
299 V_BSTR(&var_frame_name
) = NULL
;
301 V_BSTR(&var_frame_name
) = NULL
;
303 V_VT(params
+3) = VT_VARIANT
|VT_BYREF
;
304 V_VARIANTREF(params
+3) = &var_url
;
305 V_VT(&var_url
) = VT_BSTR
;
306 V_BSTR(&var_url
) = url
;
308 V_VT(params
+4) = VT_DISPATCH
;
309 V_DISPATCH(params
+4) = doc_host
->disp
;
311 call_sink(doc_host
->cps
.wbe2
, DISPID_NAVIGATEERROR
, &dispparams
);
312 SysFreeString(V_BSTR(&var_frame_name
));
315 FIXME("Navigate to error page\n");
318 static HRESULT WINAPI
BindStatusCallback_OnStopBinding(IBindStatusCallback
*iface
,
319 HRESULT hresult
, LPCWSTR szError
)
321 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
323 TRACE("(%p)->(%08x %s)\n", This
, hresult
, debugstr_w(szError
));
325 set_status_text(This
, emptyW
);
331 handle_navigation_error(This
->doc_host
, hresult
, This
->url
, NULL
);
333 IOleClientSite_Release(&This
->doc_host
->IOleClientSite_iface
);
334 This
->doc_host
= NULL
;
336 IBinding_Release(This
->binding
);
337 This
->binding
= NULL
;
342 static HRESULT WINAPI
BindStatusCallback_GetBindInfo(IBindStatusCallback
*iface
,
343 DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
345 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
347 TRACE("(%p)->(%p %p)\n", This
, grfBINDF
, pbindinfo
);
349 *grfBINDF
= BINDF_ASYNCHRONOUS
;
351 if(This
->post_data
) {
352 pbindinfo
->dwBindVerb
= BINDVERB_POST
;
354 pbindinfo
->stgmedData
.tymed
= TYMED_HGLOBAL
;
355 pbindinfo
->stgmedData
.u
.hGlobal
= This
->post_data
;
356 pbindinfo
->cbstgmedData
= This
->post_data_len
;
357 pbindinfo
->stgmedData
.pUnkForRelease
= (IUnknown
*)&This
->IBindStatusCallback_iface
;
358 IBindStatusCallback_AddRef(&This
->IBindStatusCallback_iface
);
364 static HRESULT WINAPI
BindStatusCallback_OnDataAvailable(IBindStatusCallback
*iface
,
365 DWORD grfBSCF
, DWORD dwSize
, FORMATETC
*pformatetc
, STGMEDIUM
*pstgmed
)
367 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
368 FIXME("(%p)->(%08x %d %p %p)\n", This
, grfBSCF
, dwSize
, pformatetc
, pstgmed
);
372 static HRESULT WINAPI
BindStatusCallback_OnObjectAvailable(IBindStatusCallback
*iface
,
373 REFIID riid
, IUnknown
*punk
)
375 BindStatusCallback
*This
= impl_from_IBindStatusCallback(iface
);
377 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), punk
);
379 return dochost_object_available(This
->doc_host
, punk
);
382 static const IBindStatusCallbackVtbl BindStatusCallbackVtbl
= {
383 BindStatusCallback_QueryInterface
,
384 BindStatusCallback_AddRef
,
385 BindStatusCallback_Release
,
386 BindStatusCallback_OnStartBinding
,
387 BindStatusCallback_GetPriority
,
388 BindStatusCallback_OnLowResource
,
389 BindStatusCallback_OnProgress
,
390 BindStatusCallback_OnStopBinding
,
391 BindStatusCallback_GetBindInfo
,
392 BindStatusCallback_OnDataAvailable
,
393 BindStatusCallback_OnObjectAvailable
396 static inline BindStatusCallback
*impl_from_IHttpNegotiate(IHttpNegotiate
*iface
)
398 return CONTAINING_RECORD(iface
, BindStatusCallback
, IHttpNegotiate_iface
);
401 static HRESULT WINAPI
HttpNegotiate_QueryInterface(IHttpNegotiate
*iface
,
402 REFIID riid
, void **ppv
)
404 BindStatusCallback
*This
= impl_from_IHttpNegotiate(iface
);
405 return IBindStatusCallback_QueryInterface(&This
->IBindStatusCallback_iface
, riid
, ppv
);
408 static ULONG WINAPI
HttpNegotiate_AddRef(IHttpNegotiate
*iface
)
410 BindStatusCallback
*This
= impl_from_IHttpNegotiate(iface
);
411 return IBindStatusCallback_AddRef(&This
->IBindStatusCallback_iface
);
414 static ULONG WINAPI
HttpNegotiate_Release(IHttpNegotiate
*iface
)
416 BindStatusCallback
*This
= impl_from_IHttpNegotiate(iface
);
417 return IBindStatusCallback_Release(&This
->IBindStatusCallback_iface
);
420 static HRESULT WINAPI
HttpNegotiate_BeginningTransaction(IHttpNegotiate
*iface
,
421 LPCWSTR szURL
, LPCWSTR szHeaders
, DWORD dwReserved
, LPWSTR
*pszAdditionalHeaders
)
423 BindStatusCallback
*This
= impl_from_IHttpNegotiate(iface
);
425 TRACE("(%p)->(%s %s %d %p)\n", This
, debugstr_w(szURL
), debugstr_w(szHeaders
),
426 dwReserved
, pszAdditionalHeaders
);
429 int size
= (strlenW(This
->headers
)+1)*sizeof(WCHAR
);
430 *pszAdditionalHeaders
= CoTaskMemAlloc(size
);
431 memcpy(*pszAdditionalHeaders
, This
->headers
, size
);
437 static HRESULT WINAPI
HttpNegotiate_OnResponse(IHttpNegotiate
*iface
,
438 DWORD dwResponseCode
, LPCWSTR szResponseHeaders
, LPCWSTR szRequestHeaders
,
439 LPWSTR
*pszAdditionalRequestHeaders
)
441 BindStatusCallback
*This
= impl_from_IHttpNegotiate(iface
);
442 TRACE("(%p)->(%d %s %s %p)\n", This
, dwResponseCode
, debugstr_w(szResponseHeaders
),
443 debugstr_w(szRequestHeaders
), pszAdditionalRequestHeaders
);
447 static const IHttpNegotiateVtbl HttpNegotiateVtbl
= {
448 HttpNegotiate_QueryInterface
,
449 HttpNegotiate_AddRef
,
450 HttpNegotiate_Release
,
451 HttpNegotiate_BeginningTransaction
,
452 HttpNegotiate_OnResponse
455 static BindStatusCallback
*create_callback(DocHost
*doc_host
, LPCWSTR url
, PBYTE post_data
,
456 ULONG post_data_len
, LPCWSTR headers
)
458 BindStatusCallback
*ret
= heap_alloc(sizeof(BindStatusCallback
));
460 ret
->IBindStatusCallback_iface
.lpVtbl
= &BindStatusCallbackVtbl
;
461 ret
->IHttpNegotiate_iface
.lpVtbl
= &HttpNegotiateVtbl
;
464 ret
->url
= heap_strdupW(url
);
465 ret
->post_data
= NULL
;
466 ret
->post_data_len
= post_data_len
;
467 ret
->headers
= headers
? SysAllocString(headers
) : NULL
;
469 ret
->doc_host
= doc_host
;
470 IOleClientSite_AddRef(&doc_host
->IOleClientSite_iface
);
475 ret
->post_data
= GlobalAlloc(0, post_data_len
);
476 memcpy(ret
->post_data
, post_data
, post_data_len
);
482 static void on_before_navigate2(DocHost
*This
, LPCWSTR url
, SAFEARRAY
*post_data
, LPWSTR headers
, VARIANT_BOOL
*cancel
)
484 VARIANT var_url
, var_flags
, var_frame_name
, var_post_data
, var_post_data2
, var_headers
;
485 DISPPARAMS dispparams
;
486 VARIANTARG params
[7];
488 dispparams
.cArgs
= 7;
489 dispparams
.cNamedArgs
= 0;
490 dispparams
.rgdispidNamedArgs
= NULL
;
491 dispparams
.rgvarg
= params
;
493 This
->busy
= VARIANT_TRUE
;
495 V_VT(params
) = VT_BOOL
|VT_BYREF
;
496 V_BOOLREF(params
) = cancel
;
498 V_VT(params
+1) = (VT_BYREF
|VT_VARIANT
);
499 V_VARIANTREF(params
+1) = &var_headers
;
500 V_VT(&var_headers
) = VT_BSTR
;
501 V_BSTR(&var_headers
) = headers
;
503 V_VT(params
+2) = (VT_BYREF
|VT_VARIANT
);
504 V_VARIANTREF(params
+2) = &var_post_data2
;
505 V_VT(&var_post_data2
) = (VT_BYREF
|VT_VARIANT
);
506 V_VARIANTREF(&var_post_data2
) = &var_post_data
;
509 V_VT(&var_post_data
) = VT_UI1
|VT_ARRAY
;
510 V_ARRAY(&var_post_data
) = post_data
;
512 V_VT(&var_post_data
) = VT_EMPTY
;
515 V_VT(params
+3) = (VT_BYREF
|VT_VARIANT
);
516 V_VARIANTREF(params
+3) = &var_frame_name
;
517 V_VT(&var_frame_name
) = VT_BSTR
;
518 V_BSTR(&var_frame_name
) = NULL
;
520 V_VT(params
+4) = (VT_BYREF
|VT_VARIANT
);
521 V_VARIANTREF(params
+4) = &var_flags
;
522 V_VT(&var_flags
) = VT_I4
;
523 V_I4(&var_flags
) = 0;
525 V_VT(params
+5) = (VT_BYREF
|VT_VARIANT
);
526 V_VARIANTREF(params
+5) = &var_url
;
527 V_VT(&var_url
) = VT_BSTR
;
528 V_BSTR(&var_url
) = SysAllocString(url
);
530 V_VT(params
+6) = (VT_DISPATCH
);
531 V_DISPATCH(params
+6) = This
->disp
;
533 call_sink(This
->cps
.wbe2
, DISPID_BEFORENAVIGATE2
, &dispparams
);
535 SysFreeString(V_BSTR(&var_url
));
538 /* FIXME: urlmon should handle it */
539 static BOOL
try_application_url(LPCWSTR url
)
541 SHELLEXECUTEINFOW exec_info
;
547 static const WCHAR wszURLProtocol
[] = {'U','R','L',' ','P','r','o','t','o','c','o','l',0};
549 hres
= CoInternetParseUrl(url
, PARSE_SCHEMA
, 0, app
, sizeof(app
)/sizeof(WCHAR
), NULL
, 0);
553 res
= RegOpenKeyW(HKEY_CLASSES_ROOT
, app
, &hkey
);
554 if(res
!= ERROR_SUCCESS
)
557 res
= RegQueryValueExW(hkey
, wszURLProtocol
, NULL
, &type
, NULL
, NULL
);
559 if(res
!= ERROR_SUCCESS
|| type
!= REG_SZ
)
562 TRACE("openning application %s\n", debugstr_w(app
));
564 memset(&exec_info
, 0, sizeof(exec_info
));
565 exec_info
.cbSize
= sizeof(exec_info
);
566 exec_info
.lpFile
= url
;
567 exec_info
.nShow
= SW_SHOW
;
569 return ShellExecuteExW(&exec_info
);
572 static HRESULT
create_moniker(LPCWSTR url
, IMoniker
**mon
)
574 WCHAR new_url
[INTERNET_MAX_URL_LENGTH
];
579 return CreateURLMoniker(NULL
, url
, mon
);
581 size
= sizeof(new_url
)/sizeof(WCHAR
);
582 hres
= UrlApplySchemeW(url
, new_url
, &size
, URL_APPLY_GUESSSCHEME
| URL_APPLY_GUESSFILE
);
583 TRACE("was %s got %s\n", debugstr_w(url
), debugstr_w(new_url
));
585 WARN("UrlApplyScheme failed: %08x\n", hres
);
589 return CreateURLMoniker(NULL
, new_url
, mon
);
592 static HRESULT
bind_to_object(DocHost
*This
, IMoniker
*mon
, LPCWSTR url
, IBindCtx
*bindctx
,
593 IBindStatusCallback
*callback
)
595 IUnknown
*unk
= NULL
;
600 IMoniker_AddRef(mon
);
602 hres
= create_moniker(url
, &mon
);
607 hres
= IMoniker_GetDisplayName(mon
, 0, NULL
, &display_name
);
609 FIXME("GetDisplayName failed: %08x\n", hres
);
613 hres
= set_dochost_url(This
, display_name
);
614 CoTaskMemFree(display_name
);
618 IBindCtx_RegisterObjectParam(bindctx
, (LPOLESTR
)SZ_HTML_CLIENTSITE_OBJECTPARAM
,
619 (IUnknown
*)&This
->IOleClientSite_iface
);
621 hres
= IMoniker_BindToObject(mon
, bindctx
, NULL
, &IID_IUnknown
, (void**)&unk
);
622 if(SUCCEEDED(hres
)) {
625 IUnknown_Release(unk
);
626 }else if(try_application_url(url
)) {
629 FIXME("BindToObject failed: %08x\n", hres
);
632 IMoniker_Release(mon
);
636 static void html_window_navigate(DocHost
*This
, IHTMLPrivateWindow
*window
, BSTR url
, BSTR headers
, SAFEARRAY
*post_data
)
638 VARIANT headers_var
, post_data_var
;
642 hres
= set_dochost_url(This
, url
);
646 empty_str
= SysAllocStringLen(NULL
, 0);
649 V_VT(&headers_var
) = VT_BSTR
;
650 V_BSTR(&headers_var
) = headers
;
652 V_VT(&headers_var
) = VT_EMPTY
;
656 V_VT(&post_data_var
) = VT_UI1
|VT_ARRAY
;
657 V_ARRAY(&post_data_var
) = post_data
;
659 V_VT(&post_data_var
) = VT_EMPTY
;
662 set_doc_state(This
, READYSTATE_LOADING
);
663 hres
= IHTMLPrivateWindow_SuperNavigate(window
, url
, empty_str
, NULL
, NULL
, &post_data_var
, &headers_var
, 0);
664 SysFreeString(empty_str
);
666 WARN("SuprtNavigate failed: %08x\n", hres
);
670 task_header_t header
;
673 SAFEARRAY
*post_data
;
675 } task_doc_navigate_t
;
677 static void doc_navigate_task_destr(task_header_t
*t
)
679 task_doc_navigate_t
*task
= (task_doc_navigate_t
*)t
;
681 SysFreeString(task
->url
);
682 SysFreeString(task
->headers
);
684 SafeArrayDestroy(task
->post_data
);
688 static void doc_navigate_proc(DocHost
*This
, task_header_t
*t
)
690 task_doc_navigate_t
*task
= (task_doc_navigate_t
*)t
;
691 IHTMLPrivateWindow
*priv_window
;
694 if(!This
->doc_navigate
) {
699 if(task
->async_notif
) {
700 VARIANT_BOOL cancel
= VARIANT_FALSE
;
701 on_before_navigate2(This
, task
->url
, task
->post_data
, task
->headers
, &cancel
);
703 TRACE("Navigation calnceled\n");
708 hres
= IUnknown_QueryInterface(This
->doc_navigate
, &IID_IHTMLPrivateWindow
, (void**)&priv_window
);
709 if(SUCCEEDED(hres
)) {
710 html_window_navigate(This
, priv_window
, task
->url
, task
->headers
, task
->post_data
);
711 IHTMLPrivateWindow_Release(priv_window
);
713 WARN("Could not get IHTMLPrivateWindow iface: %08x\n", hres
);
717 static HRESULT
async_doc_navigate(DocHost
*This
, LPCWSTR url
, LPCWSTR headers
, PBYTE post_data
, ULONG post_data_size
,
720 task_doc_navigate_t
*task
;
722 TRACE("%s\n", debugstr_w(url
));
724 task
= heap_alloc_zero(sizeof(*task
));
726 return E_OUTOFMEMORY
;
728 task
->url
= SysAllocString(url
);
730 doc_navigate_task_destr(&task
->header
);
731 return E_OUTOFMEMORY
;
735 task
->headers
= SysAllocString(headers
);
737 doc_navigate_task_destr(&task
->header
);
738 return E_OUTOFMEMORY
;
743 task
->post_data
= SafeArrayCreateVector(VT_UI1
, 0, post_data_size
);
744 if(!task
->post_data
) {
745 doc_navigate_task_destr(&task
->header
);
746 return E_OUTOFMEMORY
;
749 memcpy(task
->post_data
->pvData
, post_data
, post_data_size
);
753 VARIANT_BOOL cancel
= VARIANT_FALSE
;
755 on_before_navigate2(This
, task
->url
, task
->post_data
, task
->headers
, &cancel
);
757 TRACE("Navigation calnceled\n");
758 doc_navigate_task_destr(&task
->header
);
763 task
->async_notif
= async_notif
;
764 abort_dochost_tasks(This
, doc_navigate_proc
);
765 push_dochost_task(This
, &task
->header
, doc_navigate_proc
, doc_navigate_task_destr
, FALSE
);
769 static HRESULT
navigate_bsc(DocHost
*This
, BindStatusCallback
*bsc
, IMoniker
*mon
)
771 VARIANT_BOOL cancel
= VARIANT_FALSE
;
772 SAFEARRAY
*post_data
= NULL
;
776 set_doc_state(This
, READYSTATE_LOADING
);
779 post_data
= SafeArrayCreateVector(VT_UI1
, 0, bsc
->post_data_len
);
780 memcpy(post_data
->pvData
, post_data
, bsc
->post_data_len
);
783 on_before_navigate2(This
, bsc
->url
, post_data
, bsc
->headers
, &cancel
);
785 SafeArrayDestroy(post_data
);
787 FIXME("Navigation canceled\n");
792 deactivate_document(This
);
794 CreateAsyncBindCtx(0, &bsc
->IBindStatusCallback_iface
, 0, &bindctx
);
797 IOleInPlaceFrame_EnableModeless(This
->frame
, FALSE
);
799 hres
= bind_to_object(This
, mon
, bsc
->url
, bindctx
, &bsc
->IBindStatusCallback_iface
);
802 IOleInPlaceFrame_EnableModeless(This
->frame
, TRUE
);
804 IBindCtx_Release(bindctx
);
810 task_header_t header
;
811 BindStatusCallback
*bsc
;
812 } task_navigate_bsc_t
;
814 static void navigate_bsc_task_destr(task_header_t
*t
)
816 task_navigate_bsc_t
*task
= (task_navigate_bsc_t
*)t
;
818 IBindStatusCallback_Release(&task
->bsc
->IBindStatusCallback_iface
);
822 static void navigate_bsc_proc(DocHost
*This
, task_header_t
*t
)
824 task_navigate_bsc_t
*task
= (task_navigate_bsc_t
*)t
;
827 create_doc_view_hwnd(This
);
829 navigate_bsc(This
, task
->bsc
, NULL
);
833 HRESULT
navigate_url(DocHost
*This
, LPCWSTR url
, const VARIANT
*Flags
,
834 const VARIANT
*TargetFrameName
, VARIANT
*PostData
, VARIANT
*Headers
)
836 PBYTE post_data
= NULL
;
837 ULONG post_data_len
= 0;
838 LPWSTR headers
= NULL
;
841 TRACE("navigating to %s\n", debugstr_w(url
));
843 if((Flags
&& V_VT(Flags
) != VT_EMPTY
)
844 || (TargetFrameName
&& V_VT(TargetFrameName
) != VT_EMPTY
))
845 FIXME("Unsupported args (Flags %p:%d; TargetFrameName %p:%d)\n",
846 Flags
, Flags
? V_VT(Flags
) : -1, TargetFrameName
,
847 TargetFrameName
? V_VT(TargetFrameName
) : -1);
849 if(PostData
&& V_VT(PostData
) == (VT_ARRAY
| VT_UI1
) && V_ARRAY(PostData
)) {
850 SafeArrayAccessData(V_ARRAY(PostData
), (void**)&post_data
);
851 post_data_len
= V_ARRAY(PostData
)->rgsabound
[0].cElements
;
854 if(Headers
&& V_VT(Headers
) == VT_BSTR
) {
855 headers
= V_BSTR(Headers
);
856 TRACE("Headers: %s\n", debugstr_w(headers
));
859 set_doc_state(This
, READYSTATE_LOADING
);
860 This
->ready_state
= READYSTATE_LOADING
;
862 if(This
->doc_navigate
) {
863 WCHAR new_url
[INTERNET_MAX_URL_LENGTH
];
865 if(PathIsURLW(url
)) {
870 size
= sizeof(new_url
)/sizeof(WCHAR
);
871 hres
= UrlApplySchemeW(url
, new_url
, &size
,
872 URL_APPLY_GUESSSCHEME
| URL_APPLY_GUESSFILE
| URL_APPLY_DEFAULT
);
874 WARN("UrlApplyScheme failed: %08x\n", hres
);
879 hres
= async_doc_navigate(This
, *new_url
? new_url
: url
, headers
, post_data
,
880 post_data_len
, TRUE
);
882 task_navigate_bsc_t
*task
;
884 task
= heap_alloc(sizeof(*task
));
885 task
->bsc
= create_callback(This
, url
, post_data
, post_data_len
, headers
);
886 push_dochost_task(This
, &task
->header
, navigate_bsc_proc
, navigate_bsc_task_destr
, This
->url
== NULL
);
890 SafeArrayUnaccessData(V_ARRAY(PostData
));
895 static HRESULT
navigate_hlink(DocHost
*This
, IMoniker
*mon
, IBindCtx
*bindctx
,
896 IBindStatusCallback
*callback
)
898 IHttpNegotiate
*http_negotiate
;
899 BindStatusCallback
*bsc
;
900 PBYTE post_data
= NULL
;
901 ULONG post_data_len
= 0;
902 LPWSTR headers
= NULL
, url
;
909 hres
= IMoniker_GetDisplayName(mon
, 0, NULL
, &url
);
911 FIXME("GetDisplayName failed: %08x\n", hres
);
913 hres
= IBindStatusCallback_QueryInterface(callback
, &IID_IHttpNegotiate
,
914 (void**)&http_negotiate
);
915 if(SUCCEEDED(hres
)) {
916 static const WCHAR null_string
[] = {0};
918 IHttpNegotiate_BeginningTransaction(http_negotiate
, null_string
, null_string
, 0,
920 IHttpNegotiate_Release(http_negotiate
);
923 memset(&bindinfo
, 0, sizeof(bindinfo
));
924 bindinfo
.cbSize
= sizeof(bindinfo
);
926 hres
= IBindStatusCallback_GetBindInfo(callback
, &bindf
, &bindinfo
);
927 dump_BINDINFO(&bindinfo
);
928 if(bindinfo
.dwBindVerb
== BINDVERB_POST
) {
929 post_data_len
= bindinfo
.cbstgmedData
;
931 post_data
= bindinfo
.stgmedData
.u
.hGlobal
;
934 if(This
->doc_navigate
) {
935 hres
= async_doc_navigate(This
, url
, headers
, post_data
, post_data_len
, FALSE
);
937 bsc
= create_callback(This
, url
, post_data
, post_data_len
, headers
);
938 hres
= navigate_bsc(This
, bsc
, mon
);
939 IBindStatusCallback_Release(&bsc
->IBindStatusCallback_iface
);
943 CoTaskMemFree(headers
);
944 ReleaseBindInfo(&bindinfo
);
949 HRESULT
go_home(DocHost
*This
)
952 DWORD res
, type
, size
;
953 WCHAR wszPageName
[MAX_PATH
];
954 static const WCHAR wszAboutBlank
[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
955 static const WCHAR wszStartPage
[] = {'S','t','a','r','t',' ','P','a','g','e',0};
956 static const WCHAR wszSubKey
[] = {'S','o','f','t','w','a','r','e','\\',
957 'M','i','c','r','o','s','o','f','t','\\',
958 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
961 res
= RegOpenKeyW(HKEY_CURRENT_USER
, wszSubKey
, &hkey
);
962 if (res
!= ERROR_SUCCESS
)
963 return navigate_url(This
, wszAboutBlank
, NULL
, NULL
, NULL
, NULL
);
965 size
= sizeof(wszPageName
);
966 res
= RegQueryValueExW(hkey
, wszStartPage
, NULL
, &type
, (LPBYTE
)wszPageName
, &size
);
968 if (res
!= ERROR_SUCCESS
|| type
!= REG_SZ
)
969 return navigate_url(This
, wszAboutBlank
, NULL
, NULL
, NULL
, NULL
);
971 return navigate_url(This
, wszPageName
, NULL
, NULL
, NULL
, NULL
);
974 HRESULT
get_location_url(DocHost
*This
, BSTR
*ret
)
976 FIXME("semi-stub\n");
978 *ret
= This
->url
? SysAllocString(This
->url
) : SysAllocStringLen(NULL
, 0);
980 return E_OUTOFMEMORY
;
982 return This
->url
? S_OK
: S_FALSE
;
985 static inline HlinkFrame
*impl_from_IHlinkFrame(IHlinkFrame
*iface
)
987 return CONTAINING_RECORD(iface
, HlinkFrame
, IHlinkFrame_iface
);
990 static HRESULT WINAPI
HlinkFrame_QueryInterface(IHlinkFrame
*iface
, REFIID riid
, void **ppv
)
992 HlinkFrame
*This
= impl_from_IHlinkFrame(iface
);
993 return IUnknown_QueryInterface(This
->outer
, riid
, ppv
);
996 static ULONG WINAPI
HlinkFrame_AddRef(IHlinkFrame
*iface
)
998 HlinkFrame
*This
= impl_from_IHlinkFrame(iface
);
999 return IUnknown_AddRef(This
->outer
);
1002 static ULONG WINAPI
HlinkFrame_Release(IHlinkFrame
*iface
)
1004 HlinkFrame
*This
= impl_from_IHlinkFrame(iface
);
1005 return IUnknown_Release(This
->outer
);
1008 static HRESULT WINAPI
HlinkFrame_SetBrowseContext(IHlinkFrame
*iface
,
1009 IHlinkBrowseContext
*pihlbc
)
1011 HlinkFrame
*This
= impl_from_IHlinkFrame(iface
);
1012 FIXME("(%p)->(%p)\n", This
, pihlbc
);
1016 static HRESULT WINAPI
HlinkFrame_GetBrowseContext(IHlinkFrame
*iface
,
1017 IHlinkBrowseContext
**ppihlbc
)
1019 HlinkFrame
*This
= impl_from_IHlinkFrame(iface
);
1020 FIXME("(%p)->(%p)\n", This
, ppihlbc
);
1024 static HRESULT WINAPI
HlinkFrame_Navigate(IHlinkFrame
*iface
, DWORD grfHLNF
, LPBC pbc
,
1025 IBindStatusCallback
*pibsc
, IHlink
*pihlNavigate
)
1027 HlinkFrame
*This
= impl_from_IHlinkFrame(iface
);
1029 LPWSTR location
= NULL
;
1031 TRACE("(%p)->(%08x %p %p %p)\n", This
, grfHLNF
, pbc
, pibsc
, pihlNavigate
);
1034 FIXME("unsupported grfHLNF=%08x\n", grfHLNF
);
1036 /* Windows calls GetTargetFrameName here. */
1038 IHlink_GetMonikerReference(pihlNavigate
, 1, &mon
, &location
);
1041 FIXME("location = %s\n", debugstr_w(location
));
1042 CoTaskMemFree(location
);
1045 /* Windows calls GetHlinkSite here */
1047 if(grfHLNF
& HLNF_OPENINNEWWINDOW
) {
1048 FIXME("Not supported HLNF_OPENINNEWWINDOW\n");
1052 return navigate_hlink(This
->doc_host
, mon
, pbc
, pibsc
);
1055 static HRESULT WINAPI
HlinkFrame_OnNavigate(IHlinkFrame
*iface
, DWORD grfHLNF
,
1056 IMoniker
*pimkTarget
, LPCWSTR pwzLocation
, LPCWSTR pwzFriendlyName
, DWORD dwreserved
)
1058 HlinkFrame
*This
= impl_from_IHlinkFrame(iface
);
1059 FIXME("(%p)->(%08x %p %s %s %d)\n", This
, grfHLNF
, pimkTarget
, debugstr_w(pwzLocation
),
1060 debugstr_w(pwzFriendlyName
), dwreserved
);
1064 static HRESULT WINAPI
HlinkFrame_UpdateHlink(IHlinkFrame
*iface
, ULONG uHLID
,
1065 IMoniker
*pimkTarget
, LPCWSTR pwzLocation
, LPCWSTR pwzFriendlyName
)
1067 HlinkFrame
*This
= impl_from_IHlinkFrame(iface
);
1068 FIXME("(%p)->(%u %p %s %s)\n", This
, uHLID
, pimkTarget
, debugstr_w(pwzLocation
),
1069 debugstr_w(pwzFriendlyName
));
1073 static const IHlinkFrameVtbl HlinkFrameVtbl
= {
1074 HlinkFrame_QueryInterface
,
1077 HlinkFrame_SetBrowseContext
,
1078 HlinkFrame_GetBrowseContext
,
1079 HlinkFrame_Navigate
,
1080 HlinkFrame_OnNavigate
,
1081 HlinkFrame_UpdateHlink
1084 static inline HlinkFrame
*impl_from_ITargetFrame2(ITargetFrame2
*iface
)
1086 return CONTAINING_RECORD(iface
, HlinkFrame
, IHlinkFrame_iface
);
1089 static HRESULT WINAPI
TargetFrame2_QueryInterface(ITargetFrame2
*iface
, REFIID riid
, void **ppv
)
1091 HlinkFrame
*This
= impl_from_ITargetFrame2(iface
);
1092 return IUnknown_QueryInterface(This
->outer
, riid
, ppv
);
1095 static ULONG WINAPI
TargetFrame2_AddRef(ITargetFrame2
*iface
)
1097 HlinkFrame
*This
= impl_from_ITargetFrame2(iface
);
1098 return IUnknown_AddRef(This
->outer
);
1101 static ULONG WINAPI
TargetFrame2_Release(ITargetFrame2
*iface
)
1103 HlinkFrame
*This
= impl_from_ITargetFrame2(iface
);
1104 return IUnknown_Release(This
->outer
);
1107 static HRESULT WINAPI
TargetFrame2_SetFrameName(ITargetFrame2
*iface
, LPCWSTR pszFrameName
)
1109 HlinkFrame
*This
= impl_from_ITargetFrame2(iface
);
1110 FIXME("(%p)->(%s)\n", This
, debugstr_w(pszFrameName
));
1114 static HRESULT WINAPI
TargetFrame2_GetFrameName(ITargetFrame2
*iface
, LPWSTR
*ppszFrameName
)
1116 HlinkFrame
*This
= impl_from_ITargetFrame2(iface
);
1117 FIXME("(%p)->(%p)\n", This
, ppszFrameName
);
1121 static HRESULT WINAPI
TargetFrame2_GetParentFrame(ITargetFrame2
*iface
, IUnknown
**ppunkParent
)
1123 HlinkFrame
*This
= impl_from_ITargetFrame2(iface
);
1124 FIXME("(%p)->(%p)\n", This
, ppunkParent
);
1128 static HRESULT WINAPI
TargetFrame2_SetFrameSrc(ITargetFrame2
*iface
, LPCWSTR pszFrameSrc
)
1130 HlinkFrame
*This
= impl_from_ITargetFrame2(iface
);
1131 FIXME("(%p)->(%s)\n", This
, debugstr_w(pszFrameSrc
));
1135 static HRESULT WINAPI
TargetFrame2_GetFrameSrc(ITargetFrame2
*iface
, LPWSTR
*ppszFrameSrc
)
1137 HlinkFrame
*This
= impl_from_ITargetFrame2(iface
);
1138 FIXME("(%p)->()\n", This
);
1142 static HRESULT WINAPI
TargetFrame2_GetFramesContainer(ITargetFrame2
*iface
, IOleContainer
**ppContainer
)
1144 HlinkFrame
*This
= impl_from_ITargetFrame2(iface
);
1145 FIXME("(%p)->(%p)\n", This
, ppContainer
);
1149 static HRESULT WINAPI
TargetFrame2_SetFrameOptions(ITargetFrame2
*iface
, DWORD dwFlags
)
1151 HlinkFrame
*This
= impl_from_ITargetFrame2(iface
);
1152 FIXME("(%p)->(%x)\n", This
, dwFlags
);
1156 static HRESULT WINAPI
TargetFrame2_GetFrameOptions(ITargetFrame2
*iface
, DWORD
*pdwFlags
)
1158 HlinkFrame
*This
= impl_from_ITargetFrame2(iface
);
1159 FIXME("(%p)->(%p)\n", This
, pdwFlags
);
1163 static HRESULT WINAPI
TargetFrame2_SetFrameMargins(ITargetFrame2
*iface
, DWORD dwWidth
, DWORD dwHeight
)
1165 HlinkFrame
*This
= impl_from_ITargetFrame2(iface
);
1166 FIXME("(%p)->(%d %d)\n", This
, dwWidth
, dwHeight
);
1170 static HRESULT WINAPI
TargetFrame2_GetFrameMargins(ITargetFrame2
*iface
, DWORD
*pdwWidth
, DWORD
*pdwHeight
)
1172 HlinkFrame
*This
= impl_from_ITargetFrame2(iface
);
1173 FIXME("(%p)->(%p %p)\n", This
, pdwWidth
, pdwHeight
);
1177 static HRESULT WINAPI
TargetFrame2_FindFrame(ITargetFrame2
*iface
, LPCWSTR pszTargetName
, DWORD dwFlags
, IUnknown
**ppunkTargetFrame
)
1179 HlinkFrame
*This
= impl_from_ITargetFrame2(iface
);
1180 FIXME("(%p)->(%s %x %p)\n", This
, debugstr_w(pszTargetName
), dwFlags
, ppunkTargetFrame
);
1184 static HRESULT WINAPI
TargetFrame2_GetTargetAlias(ITargetFrame2
*iface
, LPCWSTR pszTargetName
, LPWSTR
*ppszTargetAlias
)
1186 HlinkFrame
*This
= impl_from_ITargetFrame2(iface
);
1187 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(pszTargetName
), ppszTargetAlias
);
1191 static const ITargetFrame2Vtbl TargetFrame2Vtbl
= {
1192 TargetFrame2_QueryInterface
,
1193 TargetFrame2_AddRef
,
1194 TargetFrame2_Release
,
1195 TargetFrame2_SetFrameName
,
1196 TargetFrame2_GetFrameName
,
1197 TargetFrame2_GetParentFrame
,
1198 TargetFrame2_SetFrameSrc
,
1199 TargetFrame2_GetFrameSrc
,
1200 TargetFrame2_GetFramesContainer
,
1201 TargetFrame2_SetFrameOptions
,
1202 TargetFrame2_GetFrameOptions
,
1203 TargetFrame2_SetFrameMargins
,
1204 TargetFrame2_GetFrameMargins
,
1205 TargetFrame2_FindFrame
,
1206 TargetFrame2_GetTargetAlias
1209 BOOL
HlinkFrame_QI(HlinkFrame
*This
, REFIID riid
, void **ppv
)
1211 if(IsEqualGUID(&IID_IHlinkFrame
, riid
)) {
1212 TRACE("(%p)->(IID_IHlinkFrame %p)\n", This
, ppv
);
1213 *ppv
= &This
->IHlinkFrame_iface
;
1214 }else if(IsEqualGUID(&IID_ITargetFrame2
, riid
)) {
1215 TRACE("(%p)->(IID_ITargetFrame2 %p)\n", This
, ppv
);
1216 *ppv
= &This
->ITargetFrame2_iface
;
1221 IUnknown_AddRef((IUnknown
*)*ppv
);
1225 void HlinkFrame_Init(HlinkFrame
*This
, IUnknown
*outer
, DocHost
*doc_host
)
1227 This
->IHlinkFrame_iface
.lpVtbl
= &HlinkFrameVtbl
;
1228 This
->ITargetFrame2_iface
.lpVtbl
= &TargetFrame2Vtbl
;
1230 This
->outer
= outer
;
1231 This
->doc_host
= doc_host
;