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 #define BINDSC_THIS(iface) DEFINE_THIS(BindStatusCallback, BindStatusCallback, iface)
116 static HRESULT WINAPI
BindStatusCallback_QueryInterface(IBindStatusCallback
*iface
,
117 REFIID riid
, void **ppv
)
119 BindStatusCallback
*This
= BINDSC_THIS(iface
);
123 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
124 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
126 }else if(IsEqualGUID(&IID_IBindStatusCallback
, riid
)) {
127 TRACE("(%p)->(IID_IBindStatusCallback %p)\n", This
, ppv
);
129 }else if(IsEqualGUID(&IID_IHttpNegotiate
, riid
)) {
130 TRACE("(%p)->(IID_IHttpNegotiate %p)\n", This
, ppv
);
131 *ppv
= HTTPNEG(This
);
135 IBindStatusCallback_AddRef(BINDSC(This
));
139 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
140 return E_NOINTERFACE
;
143 static ULONG WINAPI
BindStatusCallback_AddRef(IBindStatusCallback
*iface
)
145 BindStatusCallback
*This
= BINDSC_THIS(iface
);
146 LONG ref
= InterlockedIncrement(&This
->ref
);
148 TRACE("(%p) ref=%d\n", This
, ref
);
153 static ULONG WINAPI
BindStatusCallback_Release(IBindStatusCallback
*iface
)
155 BindStatusCallback
*This
= BINDSC_THIS(iface
);
156 LONG ref
= InterlockedDecrement(&This
->ref
);
158 TRACE("(%p) ref=%d\n", This
, ref
);
162 IOleClientSite_Release(CLIENTSITE(This
->doc_host
));
164 GlobalFree(This
->post_data
);
165 SysFreeString(This
->headers
);
166 heap_free(This
->url
);
173 static HRESULT WINAPI
BindStatusCallback_OnStartBinding(IBindStatusCallback
*iface
,
174 DWORD dwReserved
, IBinding
*pbind
)
176 BindStatusCallback
*This
= BINDSC_THIS(iface
);
178 TRACE("(%p)->(%d %p)\n", This
, dwReserved
, pbind
);
183 static HRESULT WINAPI
BindStatusCallback_GetPriority(IBindStatusCallback
*iface
,
186 BindStatusCallback
*This
= BINDSC_THIS(iface
);
187 FIXME("(%p)->(%p)\n", This
, pnPriority
);
191 static HRESULT WINAPI
BindStatusCallback_OnLowResource(IBindStatusCallback
*iface
,
194 BindStatusCallback
*This
= BINDSC_THIS(iface
);
195 FIXME("(%p)->(%d)\n", This
, reserved
);
199 static HRESULT WINAPI
BindStatusCallback_OnProgress(IBindStatusCallback
*iface
,
200 ULONG ulProgress
, ULONG ulProgressMax
, ULONG ulStatusCode
, LPCWSTR szStatusText
)
202 BindStatusCallback
*This
= BINDSC_THIS(iface
);
204 TRACE("(%p)->(%d %d %d %s)\n", This
, ulProgress
, ulProgressMax
, ulStatusCode
,
205 debugstr_w(szStatusText
));
207 switch(ulStatusCode
) {
208 case BINDSTATUS_BEGINDOWNLOADDATA
:
209 set_status_text(This
, szStatusText
); /* FIXME: "Start downloading from site: %s" */
211 case BINDSTATUS_ENDDOWNLOADDATA
:
212 set_status_text(This
, szStatusText
); /* FIXME: "Downloading from site: %s" */
214 case BINDSTATUS_CLASSIDAVAILABLE
:
215 case BINDSTATUS_MIMETYPEAVAILABLE
:
216 case BINDSTATUS_BEGINSYNCOPERATION
:
217 case BINDSTATUS_ENDSYNCOPERATION
:
220 FIXME("status code %u\n", ulStatusCode
);
226 static HRESULT WINAPI
BindStatusCallback_OnStopBinding(IBindStatusCallback
*iface
,
227 HRESULT hresult
, LPCWSTR szError
)
229 BindStatusCallback
*This
= BINDSC_THIS(iface
);
231 TRACE("(%p)->(%08x %s)\n", This
, hresult
, debugstr_w(szError
));
233 set_status_text(This
, emptyW
);
236 IOleClientSite_Release(CLIENTSITE(This
->doc_host
));
237 This
->doc_host
= NULL
;
243 static HRESULT WINAPI
BindStatusCallback_GetBindInfo(IBindStatusCallback
*iface
,
244 DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
246 BindStatusCallback
*This
= BINDSC_THIS(iface
);
248 TRACE("(%p)->(%p %p)\n", This
, grfBINDF
, pbindinfo
);
250 *grfBINDF
= BINDF_ASYNCHRONOUS
;
252 if(This
->post_data
) {
253 pbindinfo
->dwBindVerb
= BINDVERB_POST
;
255 pbindinfo
->stgmedData
.tymed
= TYMED_HGLOBAL
;
256 pbindinfo
->stgmedData
.u
.hGlobal
= This
->post_data
;
257 pbindinfo
->cbstgmedData
= This
->post_data_len
;
258 pbindinfo
->stgmedData
.pUnkForRelease
= (IUnknown
*)BINDSC(This
);
259 IBindStatusCallback_AddRef(BINDSC(This
));
265 static HRESULT WINAPI
BindStatusCallback_OnDataAvailable(IBindStatusCallback
*iface
,
266 DWORD grfBSCF
, DWORD dwSize
, FORMATETC
*pformatetc
, STGMEDIUM
*pstgmed
)
268 BindStatusCallback
*This
= BINDSC_THIS(iface
);
269 FIXME("(%p)->(%08x %d %p %p)\n", This
, grfBSCF
, dwSize
, pformatetc
, pstgmed
);
273 static void object_available_proc(DocHost
*This
, task_header_t
*task
)
275 object_available(This
);
278 static HRESULT WINAPI
BindStatusCallback_OnObjectAvailable(IBindStatusCallback
*iface
,
279 REFIID riid
, IUnknown
*punk
)
281 BindStatusCallback
*This
= BINDSC_THIS(iface
);
286 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), punk
);
288 IUnknown_AddRef(punk
);
289 This
->doc_host
->document
= punk
;
291 hres
= IUnknown_QueryInterface(punk
, &IID_IOleObject
, (void**)&oleobj
);
292 if(SUCCEEDED(hres
)) {
295 hres
= IOleObject_GetUserClassID(oleobj
, &clsid
);
297 TRACE("Got clsid %s\n",
298 IsEqualGUID(&clsid
, &CLSID_HTMLDocument
) ? "CLSID_HTMLDocument" : debugstr_guid(&clsid
));
300 hres
= IOleObject_SetClientSite(oleobj
, CLIENTSITE(This
->doc_host
));
302 FIXME("SetClientSite failed: %08x\n", hres
);
304 IOleObject_Release(oleobj
);
306 FIXME("Could not get IOleObject iface: %08x\n", hres
);
309 /* FIXME: Call SetAdvise */
310 /* FIXME: Call Invoke(DISPID_READYSTATE) */
312 task
= heap_alloc(sizeof(*task
));
313 push_dochost_task(This
->doc_host
, task
, object_available_proc
, FALSE
);
320 static const IBindStatusCallbackVtbl BindStatusCallbackVtbl
= {
321 BindStatusCallback_QueryInterface
,
322 BindStatusCallback_AddRef
,
323 BindStatusCallback_Release
,
324 BindStatusCallback_OnStartBinding
,
325 BindStatusCallback_GetPriority
,
326 BindStatusCallback_OnLowResource
,
327 BindStatusCallback_OnProgress
,
328 BindStatusCallback_OnStopBinding
,
329 BindStatusCallback_GetBindInfo
,
330 BindStatusCallback_OnDataAvailable
,
331 BindStatusCallback_OnObjectAvailable
334 #define HTTPNEG_THIS(iface) DEFINE_THIS(BindStatusCallback, HttpNegotiate, iface)
336 static HRESULT WINAPI
HttpNegotiate_QueryInterface(IHttpNegotiate
*iface
,
337 REFIID riid
, void **ppv
)
339 BindStatusCallback
*This
= HTTPNEG_THIS(iface
);
340 return IBindStatusCallback_QueryInterface(BINDSC(This
), riid
, ppv
);
343 static ULONG WINAPI
HttpNegotiate_AddRef(IHttpNegotiate
*iface
)
345 BindStatusCallback
*This
= HTTPNEG_THIS(iface
);
346 return IBindStatusCallback_AddRef(BINDSC(This
));
349 static ULONG WINAPI
HttpNegotiate_Release(IHttpNegotiate
*iface
)
351 BindStatusCallback
*This
= HTTPNEG_THIS(iface
);
352 return IBindStatusCallback_Release(BINDSC(This
));
355 static HRESULT WINAPI
HttpNegotiate_BeginningTransaction(IHttpNegotiate
*iface
,
356 LPCWSTR szURL
, LPCWSTR szHeaders
, DWORD dwReserved
, LPWSTR
*pszAdditionalHeaders
)
358 BindStatusCallback
*This
= HTTPNEG_THIS(iface
);
360 FIXME("(%p)->(%s %s %d %p)\n", This
, debugstr_w(szURL
), debugstr_w(szHeaders
),
361 dwReserved
, pszAdditionalHeaders
);
364 int size
= (strlenW(This
->headers
)+1)*sizeof(WCHAR
);
365 *pszAdditionalHeaders
= CoTaskMemAlloc(size
);
366 memcpy(*pszAdditionalHeaders
, This
->headers
, size
);
372 static HRESULT WINAPI
HttpNegotiate_OnResponse(IHttpNegotiate
*iface
,
373 DWORD dwResponseCode
, LPCWSTR szResponseHeaders
, LPCWSTR szRequestHeaders
,
374 LPWSTR
*pszAdditionalRequestHeaders
)
376 BindStatusCallback
*This
= HTTPNEG_THIS(iface
);
377 FIXME("(%p)->(%d %s %s %p)\n", This
, dwResponseCode
, debugstr_w(szResponseHeaders
),
378 debugstr_w(szRequestHeaders
), pszAdditionalRequestHeaders
);
384 static const IHttpNegotiateVtbl HttpNegotiateVtbl
= {
385 HttpNegotiate_QueryInterface
,
386 HttpNegotiate_AddRef
,
387 HttpNegotiate_Release
,
388 HttpNegotiate_BeginningTransaction
,
389 HttpNegotiate_OnResponse
392 static BindStatusCallback
*create_callback(DocHost
*doc_host
, LPCWSTR url
, PBYTE post_data
,
393 ULONG post_data_len
, LPCWSTR headers
)
395 BindStatusCallback
*ret
= heap_alloc(sizeof(BindStatusCallback
));
397 ret
->lpBindStatusCallbackVtbl
= &BindStatusCallbackVtbl
;
398 ret
->lpHttpNegotiateVtbl
= &HttpNegotiateVtbl
;
401 ret
->url
= heap_strdupW(url
);
402 ret
->post_data
= NULL
;
403 ret
->post_data_len
= post_data_len
;
404 ret
->headers
= headers
? SysAllocString(headers
) : NULL
;
406 ret
->doc_host
= doc_host
;
407 IOleClientSite_AddRef(CLIENTSITE(doc_host
));
410 ret
->post_data
= GlobalAlloc(0, post_data_len
);
411 memcpy(ret
->post_data
, post_data
, post_data_len
);
417 static void on_before_navigate2(DocHost
*This
, LPCWSTR url
, const BYTE
*post_data
,
418 ULONG post_data_len
, LPWSTR headers
, VARIANT_BOOL
*cancel
)
420 VARIANT var_url
, var_flags
, var_frame_name
, var_post_data
, var_post_data2
, var_headers
;
421 DISPPARAMS dispparams
;
422 VARIANTARG params
[7];
424 dispparams
.cArgs
= 7;
425 dispparams
.cNamedArgs
= 0;
426 dispparams
.rgdispidNamedArgs
= NULL
;
427 dispparams
.rgvarg
= params
;
429 This
->busy
= VARIANT_TRUE
;
431 V_VT(params
) = VT_BOOL
|VT_BYREF
;
432 V_BOOLREF(params
) = cancel
;
434 V_VT(params
+1) = (VT_BYREF
|VT_VARIANT
);
435 V_VARIANTREF(params
+1) = &var_headers
;
436 V_VT(&var_headers
) = VT_BSTR
;
437 V_BSTR(&var_headers
) = headers
;
439 V_VT(params
+2) = (VT_BYREF
|VT_VARIANT
);
440 V_VARIANTREF(params
+2) = &var_post_data2
;
441 V_VT(&var_post_data2
) = (VT_BYREF
|VT_VARIANT
);
442 V_VARIANTREF(&var_post_data2
) = &var_post_data
;
443 VariantInit(&var_post_data
);
446 SAFEARRAYBOUND bound
= {post_data_len
, 0};
449 V_VT(&var_post_data
) = VT_UI1
|VT_ARRAY
;
450 V_ARRAY(&var_post_data
) = SafeArrayCreate(VT_UI1
, 1, &bound
);
452 SafeArrayAccessData(V_ARRAY(&var_post_data
), &data
);
453 memcpy(data
, post_data
, post_data_len
);
454 SafeArrayUnaccessData(V_ARRAY(&var_post_data
));
457 V_VT(params
+3) = (VT_BYREF
|VT_VARIANT
);
458 V_VARIANTREF(params
+3) = &var_frame_name
;
459 V_VT(&var_frame_name
) = VT_BSTR
;
460 V_BSTR(&var_frame_name
) = NULL
;
462 V_VT(params
+4) = (VT_BYREF
|VT_VARIANT
);
463 V_VARIANTREF(params
+4) = &var_flags
;
464 V_VT(&var_flags
) = VT_I4
;
465 V_I4(&var_flags
) = 0;
467 V_VT(params
+5) = (VT_BYREF
|VT_VARIANT
);
468 V_VARIANTREF(params
+5) = &var_url
;
469 V_VT(&var_url
) = VT_BSTR
;
470 V_BSTR(&var_url
) = SysAllocString(url
);
472 V_VT(params
+6) = (VT_DISPATCH
);
473 V_DISPATCH(params
+6) = This
->disp
;
475 call_sink(This
->cps
.wbe2
, DISPID_BEFORENAVIGATE2
, &dispparams
);
477 SysFreeString(V_BSTR(&var_url
));
479 SafeArrayDestroy(V_ARRAY(&var_post_data
));
482 /* FIXME: urlmon should handle it */
483 static BOOL
try_application_url(LPCWSTR url
)
485 SHELLEXECUTEINFOW exec_info
;
491 static const WCHAR wszURLProtocol
[] = {'U','R','L',' ','P','r','o','t','o','c','o','l',0};
493 hres
= CoInternetParseUrl(url
, PARSE_SCHEMA
, 0, app
, sizeof(app
)/sizeof(WCHAR
), NULL
, 0);
497 res
= RegOpenKeyW(HKEY_CLASSES_ROOT
, app
, &hkey
);
498 if(res
!= ERROR_SUCCESS
)
501 res
= RegQueryValueExW(hkey
, wszURLProtocol
, NULL
, &type
, NULL
, NULL
);
503 if(res
!= ERROR_SUCCESS
|| type
!= REG_SZ
)
506 TRACE("openning application %s\n", debugstr_w(app
));
508 memset(&exec_info
, 0, sizeof(exec_info
));
509 exec_info
.cbSize
= sizeof(exec_info
);
510 exec_info
.lpFile
= url
;
511 exec_info
.nShow
= SW_SHOW
;
513 return ShellExecuteExW(&exec_info
);
516 static HRESULT
http_load_hack(DocHost
*This
, IMoniker
*mon
, IBindStatusCallback
*callback
, IBindCtx
*bindctx
)
518 IPersistMoniker
*persist
;
524 * We should use URLMoniker's BindToObject instead creating HTMLDocument here.
525 * This should be fixed when mshtml.dll and urlmon.dll will be good enough.
528 hres
= CoCreateInstance(&CLSID_HTMLDocument
, NULL
,
529 CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
530 &IID_IUnknown
, (void**)&doc
);
533 ERR("Could not create HTMLDocument: %08x\n", hres
);
537 hres
= IUnknown_QueryInterface(doc
, &IID_IPersistMoniker
, (void**)&persist
);
539 IUnknown_Release(doc
);
543 hres
= IPersistMoniker_Load(persist
, FALSE
, mon
, bindctx
, 0);
544 IPersistMoniker_Release(persist
);
547 hres
= IBindStatusCallback_OnObjectAvailable(callback
, &IID_IUnknown
, doc
);
549 WARN("Load failed: %08x\n", hres
);
551 IUnknown_Release(doc
);
553 return IBindStatusCallback_OnStopBinding(callback
, hres
, NULL
);
556 static HRESULT
create_moniker(LPCWSTR url
, IMoniker
**mon
)
558 WCHAR new_url
[INTERNET_MAX_URL_LENGTH
];
563 return CreateURLMoniker(NULL
, url
, mon
);
566 size
= sizeof(new_url
);
567 hres
= UrlCreateFromPathW(url
, new_url
, &size
, 0);
569 WARN("UrlCreateFromPathW failed: %08x\n", hres
);
573 size
= sizeof(new_url
);
574 hres
= UrlApplySchemeW(url
, new_url
, &size
, URL_APPLY_GUESSSCHEME
);
575 TRACE("got %s\n", debugstr_w(new_url
));
577 WARN("UrlApplyScheme failed: %08x\n", hres
);
582 return CreateURLMoniker(NULL
, new_url
, mon
);
585 static HRESULT
bind_to_object(DocHost
*This
, IMoniker
*mon
, LPCWSTR url
, IBindCtx
*bindctx
,
586 IBindStatusCallback
*callback
)
592 static const WCHAR httpW
[] = {'h','t','t','p',0};
593 static const WCHAR httpsW
[] = {'h','t','t','p','s',0};
594 static const WCHAR ftpW
[]= {'f','t','p',0};
597 IMoniker_AddRef(mon
);
599 hres
= create_moniker(url
, &mon
);
604 CoTaskMemFree(This
->url
);
605 hres
= IMoniker_GetDisplayName(mon
, 0, NULL
, &This
->url
);
607 FIXME("GetDisplayName failed: %08x\n", hres
);
609 IBindCtx_RegisterObjectParam(bindctx
, (LPOLESTR
)SZ_HTML_CLIENTSITE_OBJECTPARAM
,
610 (IUnknown
*)CLIENTSITE(This
));
612 hres
= CoInternetParseUrl(This
->url
, PARSE_SCHEMA
, 0, schema
, sizeof(schema
)/sizeof(schema
[0]),
614 if(SUCCEEDED(hres
) &&
615 (!strcmpW(schema
, httpW
) || !strcmpW(schema
, httpsW
) || !strcmpW(schema
, ftpW
))) {
616 hres
= http_load_hack(This
, mon
, callback
, bindctx
);
618 IUnknown
*unk
= NULL
;
620 hres
= IMoniker_BindToObject(mon
, bindctx
, NULL
, &IID_IUnknown
, (void**)&unk
);
621 if(SUCCEEDED(hres
)) {
624 IUnknown_Release(unk
);
625 }else if(try_application_url(url
)) {
628 FIXME("BindToObject failed: %08x\n", hres
);
632 IMoniker_Release(mon
);
636 static HRESULT
navigate_bsc(DocHost
*This
, BindStatusCallback
*bsc
, IMoniker
*mon
)
639 VARIANT_BOOL cancel
= VARIANT_FALSE
;
642 on_before_navigate2(This
, bsc
->url
, bsc
->post_data
, bsc
->post_data_len
, bsc
->headers
, &cancel
);
644 FIXME("Navigation canceled\n");
649 deactivate_document(This
);
651 CreateAsyncBindCtx(0, BINDSC(bsc
), 0, &bindctx
);
654 IOleInPlaceFrame_EnableModeless(This
->frame
, FALSE
);
656 hres
= bind_to_object(This
, mon
, bsc
->url
, bindctx
, BINDSC(bsc
));
659 IOleInPlaceFrame_EnableModeless(This
->frame
, TRUE
);
661 IBindCtx_Release(bindctx
);
667 task_header_t header
;
668 BindStatusCallback
*bsc
;
669 } task_navigate_bsc_t
;
671 static void navigate_bsc_proc(DocHost
*This
, task_header_t
*t
)
673 task_navigate_bsc_t
*task
= (task_navigate_bsc_t
*)t
;
676 create_doc_view_hwnd(This
);
678 navigate_bsc(This
, task
->bsc
, NULL
);
680 IBindStatusCallback_Release(BINDSC(task
->bsc
));
684 HRESULT
navigate_url(DocHost
*This
, LPCWSTR url
, const VARIANT
*Flags
,
685 const VARIANT
*TargetFrameName
, VARIANT
*PostData
, VARIANT
*Headers
)
687 task_navigate_bsc_t
*task
;
688 PBYTE post_data
= NULL
;
689 ULONG post_data_len
= 0;
690 LPWSTR headers
= NULL
;
692 TRACE("navigating to %s\n", debugstr_w(url
));
694 if((Flags
&& V_VT(Flags
) != VT_EMPTY
)
695 || (TargetFrameName
&& V_VT(TargetFrameName
) != VT_EMPTY
))
696 FIXME("Unsupported args (Flags %p:%d; TargetFrameName %p:%d)\n",
697 Flags
, Flags
? V_VT(Flags
) : -1, TargetFrameName
,
698 TargetFrameName
? V_VT(TargetFrameName
) : -1);
701 TRACE("PostData vt=%d\n", V_VT(PostData
));
703 if(V_VT(PostData
) == (VT_ARRAY
| VT_UI1
)) {
704 SafeArrayAccessData(V_ARRAY(PostData
), (void**)&post_data
);
705 post_data_len
= V_ARRAY(PostData
)->rgsabound
[0].cElements
;
709 if(Headers
&& V_VT(Headers
) != VT_EMPTY
&& V_VT(Headers
) != VT_ERROR
) {
710 if(V_VT(Headers
) != VT_BSTR
)
713 headers
= V_BSTR(Headers
);
714 TRACE("Headers: %s\n", debugstr_w(headers
));
717 task
= heap_alloc(sizeof(*task
));
718 task
->bsc
= create_callback(This
, url
, post_data
, post_data_len
, headers
);
721 SafeArrayUnaccessData(V_ARRAY(PostData
));
723 push_dochost_task(This
, &task
->header
, navigate_bsc_proc
, This
->url
== NULL
);
728 static HRESULT
navigate_hlink(DocHost
*This
, IMoniker
*mon
, IBindCtx
*bindctx
,
729 IBindStatusCallback
*callback
)
731 IHttpNegotiate
*http_negotiate
;
732 BindStatusCallback
*bsc
;
733 PBYTE post_data
= NULL
;
734 ULONG post_data_len
= 0;
735 LPWSTR headers
= NULL
, url
;
740 hres
= IBindStatusCallback_QueryInterface(callback
, &IID_IHttpNegotiate
,
741 (void**)&http_negotiate
);
742 if(SUCCEEDED(hres
)) {
743 static const WCHAR null_string
[] = {0};
745 IHttpNegotiate_BeginningTransaction(http_negotiate
, null_string
, null_string
, 0,
747 IHttpNegotiate_Release(http_negotiate
);
750 memset(&bindinfo
, 0, sizeof(bindinfo
));
751 bindinfo
.cbSize
= sizeof(bindinfo
);
753 hres
= IBindStatusCallback_GetBindInfo(callback
, &bindf
, &bindinfo
);
754 dump_BINDINFO(&bindinfo
);
755 if(bindinfo
.dwBindVerb
== BINDVERB_POST
) {
756 post_data_len
= bindinfo
.cbstgmedData
;
758 post_data
= bindinfo
.stgmedData
.u
.hGlobal
;
761 hres
= IMoniker_GetDisplayName(mon
, 0, NULL
, &url
);
763 FIXME("GetDisplayName failed: %08x\n", hres
);
765 bsc
= create_callback(This
, url
, post_data
, post_data_len
, headers
);
768 hres
= navigate_bsc(This
, bsc
, mon
);
770 IBindStatusCallback_Release(BINDSC(bsc
));
771 CoTaskMemFree(headers
);
772 ReleaseBindInfo(&bindinfo
);
777 HRESULT
go_home(DocHost
*This
)
780 DWORD res
, type
, size
;
781 WCHAR wszPageName
[MAX_PATH
];
782 static const WCHAR wszAboutBlank
[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
783 static const WCHAR wszStartPage
[] = {'S','t','a','r','t',' ','P','a','g','e',0};
784 static const WCHAR wszSubKey
[] = {'S','o','f','t','w','a','r','e','\\',
785 'M','i','c','r','o','s','o','f','t','\\',
786 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
789 res
= RegOpenKeyW(HKEY_CURRENT_USER
, wszSubKey
, &hkey
);
790 if (res
!= ERROR_SUCCESS
)
791 return navigate_url(This
, wszAboutBlank
, NULL
, NULL
, NULL
, NULL
);
793 size
= sizeof(wszPageName
);
794 res
= RegQueryValueExW(hkey
, wszStartPage
, NULL
, &type
, (LPBYTE
)wszPageName
, &size
);
796 if (res
!= ERROR_SUCCESS
|| type
!= REG_SZ
)
797 return navigate_url(This
, wszAboutBlank
, NULL
, NULL
, NULL
, NULL
);
799 return navigate_url(This
, wszPageName
, NULL
, NULL
, NULL
, NULL
);
802 static HRESULT
open_in_new_window(IMoniker
*mon
)
804 SHELLEXECUTEINFOW exec_info
;
808 static const WCHAR wszHtmlFile
[] = {'.','h','t','m','l',0};
810 hres
= IMoniker_GetDisplayName(mon
, NULL
, NULL
, &url
);
814 memset(&exec_info
, 0, sizeof(exec_info
));
815 exec_info
.cbSize
= sizeof(exec_info
);
816 exec_info
.fMask
= SEE_MASK_CLASSNAME
;
817 exec_info
.lpFile
= url
;
818 exec_info
.nShow
= SW_SHOW
;
819 exec_info
.lpClass
= wszHtmlFile
;
821 ShellExecuteExW(&exec_info
);
828 #define HLINKFRAME_THIS(iface) DEFINE_THIS(WebBrowser, HlinkFrame, iface)
830 static HRESULT WINAPI
HlinkFrame_QueryInterface(IHlinkFrame
*iface
, REFIID riid
, void **ppv
)
832 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
833 return IWebBrowser2_QueryInterface(WEBBROWSER2(This
), riid
, ppv
);
836 static ULONG WINAPI
HlinkFrame_AddRef(IHlinkFrame
*iface
)
838 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
839 return IWebBrowser2_AddRef(WEBBROWSER2(This
));
842 static ULONG WINAPI
HlinkFrame_Release(IHlinkFrame
*iface
)
844 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
845 return IWebBrowser2_Release(WEBBROWSER2(This
));
848 static HRESULT WINAPI
HlinkFrame_SetBrowseContext(IHlinkFrame
*iface
,
849 IHlinkBrowseContext
*pihlbc
)
851 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
852 FIXME("(%p)->(%p)\n", This
, pihlbc
);
856 static HRESULT WINAPI
HlinkFrame_GetBrowseContext(IHlinkFrame
*iface
,
857 IHlinkBrowseContext
**ppihlbc
)
859 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
860 FIXME("(%p)->(%p)\n", This
, ppihlbc
);
864 static HRESULT WINAPI
HlinkFrame_Navigate(IHlinkFrame
*iface
, DWORD grfHLNF
, LPBC pbc
,
865 IBindStatusCallback
*pibsc
, IHlink
*pihlNavigate
)
867 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
869 LPWSTR location
= NULL
;
871 TRACE("(%p)->(%08x %p %p %p)\n", This
, grfHLNF
, pbc
, pibsc
, pihlNavigate
);
874 FIXME("unsupported grfHLNF=%08x\n", grfHLNF
);
876 /* Windows calls GetTargetFrameName here. */
878 IHlink_GetMonikerReference(pihlNavigate
, 1, &mon
, &location
);
881 FIXME("location = %s\n", debugstr_w(location
));
882 CoTaskMemFree(location
);
885 /* Windows calls GetHlinkSite here */
887 if(grfHLNF
& HLNF_OPENINNEWWINDOW
) {
888 FIXME("Not supported HLNF_OPENINNEWWINDOW\n");
889 return open_in_new_window(mon
);
892 return navigate_hlink(&This
->doc_host
, mon
, pbc
, pibsc
);
895 static HRESULT WINAPI
HlinkFrame_OnNavigate(IHlinkFrame
*iface
, DWORD grfHLNF
,
896 IMoniker
*pimkTarget
, LPCWSTR pwzLocation
, LPCWSTR pwzFriendlyName
, DWORD dwreserved
)
898 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
899 FIXME("(%p)->(%08x %p %s %s %d)\n", This
, grfHLNF
, pimkTarget
, debugstr_w(pwzLocation
),
900 debugstr_w(pwzFriendlyName
), dwreserved
);
904 static HRESULT WINAPI
HlinkFrame_UpdateHlink(IHlinkFrame
*iface
, ULONG uHLID
,
905 IMoniker
*pimkTarget
, LPCWSTR pwzLocation
, LPCWSTR pwzFriendlyName
)
907 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
908 FIXME("(%p)->(%u %p %s %s)\n", This
, uHLID
, pimkTarget
, debugstr_w(pwzLocation
),
909 debugstr_w(pwzFriendlyName
));
913 #undef HLINKFRAME_THIS
915 static const IHlinkFrameVtbl HlinkFrameVtbl
= {
916 HlinkFrame_QueryInterface
,
919 HlinkFrame_SetBrowseContext
,
920 HlinkFrame_GetBrowseContext
,
922 HlinkFrame_OnNavigate
,
923 HlinkFrame_UpdateHlink
926 void WebBrowser_HlinkFrame_Init(WebBrowser
*This
)
928 This
->lpHlinkFrameVtbl
= &HlinkFrameVtbl
;