2 * Copyright 2006 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #define NONAMELESSUNION
20 #define NONAMELESSSTRUCT
22 #include "wine/debug.h"
23 #include "wine/unicode.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(shdocvw
);
32 const IBindStatusCallbackVtbl
*lpBindStatusCallbackVtbl
;
33 const IHttpNegotiateVtbl
*lpHttpNegotiateVtbl
;
42 #define BINDSC(x) ((IBindStatusCallback*) &(x)->lpBindStatusCallbackVtbl)
43 #define HTTPNEG(x) ((IHttpNegotiate*) &(x)->lpHttpNegotiateVtbl)
45 static void dump_BINDINFO(BINDINFO
*bi
)
47 static const char *BINDINFOF_str
[] = {
49 "BINDINFOF_URLENCODESTGMEDDATA",
50 "BINDINFOF_URLENCODEDEXTRAINFO"
53 static const char *BINDVERB_str
[] = {
67 " %ld, %08lx, %ld, %ld\n"
73 bi
->cbSize
, debugstr_w(bi
->szExtraInfo
),
74 bi
->stgmedData
.tymed
, bi
->stgmedData
.u
.hGlobal
, bi
->stgmedData
.pUnkForRelease
,
75 bi
->grfBindInfoF
> BINDINFOF_URLENCODEDEXTRAINFO
76 ? "unknown" : BINDINFOF_str
[bi
->grfBindInfoF
],
77 bi
->dwBindVerb
> BINDVERB_CUSTOM
78 ? "unknown" : BINDVERB_str
[bi
->dwBindVerb
],
79 debugstr_w(bi
->szCustomVerb
),
80 bi
->cbStgmedData
, bi
->dwOptions
, bi
->dwOptionsFlags
, bi
->dwCodePage
,
81 bi
->securityAttributes
.nLength
,
82 bi
->securityAttributes
.lpSecurityDescriptor
,
83 bi
->securityAttributes
.bInheritHandle
,
84 debugstr_guid(&bi
->iid
),
85 bi
->pUnk
, bi
->dwReserved
89 #define BINDSC_THIS(iface) DEFINE_THIS(BindStatusCallback, BindStatusCallback, iface)
91 static HRESULT WINAPI
BindStatusCallback_QueryInterface(IBindStatusCallback
*iface
,
92 REFIID riid
, void **ppv
)
94 BindStatusCallback
*This
= BINDSC_THIS(iface
);
98 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
99 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
101 }else if(IsEqualGUID(&IID_IBindStatusCallback
, riid
)) {
102 TRACE("(%p)->(IID_IBindStatusCallback %p)\n", This
, ppv
);
104 }else if(IsEqualGUID(&IID_IHttpNegotiate
, riid
)) {
105 TRACE("(%p)->(IID_IHttpNegotiate %p)\n", This
, ppv
);
106 *ppv
= HTTPNEG(This
);
110 IBindStatusCallback_AddRef(BINDSC(This
));
114 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
115 return E_NOINTERFACE
;
118 static ULONG WINAPI
BindStatusCallback_AddRef(IBindStatusCallback
*iface
)
120 BindStatusCallback
*This
= BINDSC_THIS(iface
);
121 LONG ref
= InterlockedIncrement(&This
->ref
);
123 TRACE("(%p) ref=%ld\n", This
, ref
);
128 static ULONG WINAPI
BindStatusCallback_Release(IBindStatusCallback
*iface
)
130 BindStatusCallback
*This
= BINDSC_THIS(iface
);
131 LONG ref
= InterlockedDecrement(&This
->ref
);
133 TRACE("(%p) ref=%ld\n", This
, ref
);
137 GlobalFree(This
->post_data
);
138 HeapFree(GetProcessHeap(), 0, This
->headers
);
139 HeapFree(GetProcessHeap(), 0, This
);
145 static HRESULT WINAPI
BindStatusCallback_OnStartBinding(IBindStatusCallback
*iface
,
146 DWORD dwReserved
, IBinding
*pbind
)
148 BindStatusCallback
*This
= BINDSC_THIS(iface
);
149 FIXME("(%p)->(%ld %p)\n", This
, dwReserved
, pbind
);
153 static HRESULT WINAPI
BindStatusCallback_GetPriority(IBindStatusCallback
*iface
,
156 BindStatusCallback
*This
= BINDSC_THIS(iface
);
157 FIXME("(%p)->(%p)\n", This
, pnPriority
);
161 static HRESULT WINAPI
BindStatusCallback_OnLowResource(IBindStatusCallback
*iface
,
164 BindStatusCallback
*This
= BINDSC_THIS(iface
);
165 FIXME("(%p)->(%ld)\n", This
, reserved
);
169 static HRESULT WINAPI
BindStatusCallback_OnProgress(IBindStatusCallback
*iface
,
170 ULONG ulProgress
, ULONG ulProgressMax
, ULONG ulStatusCode
, LPCWSTR szStatusText
)
172 BindStatusCallback
*This
= BINDSC_THIS(iface
);
173 FIXME("(%p)->(%ld %ld %ld %s)\n", This
, ulProgress
, ulProgressMax
, ulStatusCode
,
174 debugstr_w(szStatusText
));
178 static HRESULT WINAPI
BindStatusCallback_OnStopBinding(IBindStatusCallback
*iface
,
179 HRESULT hresult
, LPCWSTR szError
)
181 BindStatusCallback
*This
= BINDSC_THIS(iface
);
182 FIXME("(%p)->(%08lx %s)\n", This
, hresult
, debugstr_w(szError
));
186 static HRESULT WINAPI
BindStatusCallback_GetBindInfo(IBindStatusCallback
*iface
,
187 DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
189 BindStatusCallback
*This
= BINDSC_THIS(iface
);
191 FIXME("(%p)->(%p %p)\n", This
, grfBINDF
, pbindinfo
);
193 memset(pbindinfo
, 0, sizeof(BINDINFO
));
194 pbindinfo
->cbSize
= sizeof(BINDINFO
);
196 pbindinfo
->cbStgmedData
= This
->post_data_len
;
198 if(This
->post_data
) {
199 pbindinfo
->dwBindVerb
= BINDVERB_POST
;
201 pbindinfo
->stgmedData
.tymed
= TYMED_HGLOBAL
;
202 pbindinfo
->stgmedData
.u
.hGlobal
= This
->post_data
;
203 pbindinfo
->stgmedData
.pUnkForRelease
= (IUnknown
*)BINDSC(This
);
204 IBindStatusCallback_AddRef(BINDSC(This
));
210 static HRESULT WINAPI
BindStatusCallback_OnDataAvailable(IBindStatusCallback
*iface
,
211 DWORD grfBSCF
, DWORD dwSize
, FORMATETC
*pformatetc
, STGMEDIUM
*pstgmed
)
213 BindStatusCallback
*This
= BINDSC_THIS(iface
);
214 FIXME("(%p)->(%08lx %ld %p %p)\n", This
, grfBSCF
, dwSize
, pformatetc
, pstgmed
);
220 static const IBindStatusCallbackVtbl BindStatusCallbackVtbl
= {
221 BindStatusCallback_QueryInterface
,
222 BindStatusCallback_AddRef
,
223 BindStatusCallback_Release
,
224 BindStatusCallback_OnStartBinding
,
225 BindStatusCallback_GetPriority
,
226 BindStatusCallback_OnLowResource
,
227 BindStatusCallback_OnProgress
,
228 BindStatusCallback_OnStopBinding
,
229 BindStatusCallback_GetBindInfo
,
230 BindStatusCallback_OnDataAvailable
233 #define HTTPNEG_THIS(iface) DEFINE_THIS(BindStatusCallback, HttpNegotiate, iface)
235 static HRESULT WINAPI
HttpNegotiate_QueryInterface(IHttpNegotiate
*iface
,
236 REFIID riid
, void **ppv
)
238 BindStatusCallback
*This
= HTTPNEG_THIS(iface
);
239 return IBindStatusCallback_QueryInterface(BINDSC(This
), riid
, ppv
);
242 static ULONG WINAPI
HttpNegotiate_AddRef(IHttpNegotiate
*iface
)
244 BindStatusCallback
*This
= HTTPNEG_THIS(iface
);
245 return IBindStatusCallback_AddRef(BINDSC(This
));
248 static ULONG WINAPI
HttpNegotiate_Release(IHttpNegotiate
*iface
)
250 BindStatusCallback
*This
= HTTPNEG_THIS(iface
);
251 return IBindStatusCallback_Release(BINDSC(This
));
254 static HRESULT WINAPI
HttpNegotiate_BeginningTransaction(IHttpNegotiate
*iface
,
255 LPCWSTR szURL
, LPCWSTR szHeaders
, DWORD dwReserved
, LPWSTR
*pszAdditionalHeaders
)
257 BindStatusCallback
*This
= HTTPNEG_THIS(iface
);
259 FIXME("(%p)->(%s %s %ld %p)\n", This
, debugstr_w(szURL
), debugstr_w(szHeaders
),
260 dwReserved
, pszAdditionalHeaders
);
263 int size
= (strlenW(This
->headers
)+1)*sizeof(WCHAR
);
264 *pszAdditionalHeaders
= CoTaskMemAlloc(size
);
265 memcpy(*pszAdditionalHeaders
, This
->headers
, size
);
271 static HRESULT WINAPI
HttpNegotiate_OnResponse(IHttpNegotiate
*iface
,
272 DWORD dwResponseCode
, LPCWSTR szResponseHeaders
, LPCWSTR szRequestHeaders
,
273 LPWSTR
*pszAdditionalRequestHeaders
)
275 BindStatusCallback
*This
= HTTPNEG_THIS(iface
);
276 FIXME("(%p)->(%ld %s %s %p)\n", This
, dwResponseCode
, debugstr_w(szResponseHeaders
),
277 debugstr_w(szRequestHeaders
), pszAdditionalRequestHeaders
);
283 static const IHttpNegotiateVtbl HttpNegotiateVtbl
= {
284 HttpNegotiate_QueryInterface
,
285 HttpNegotiate_AddRef
,
286 HttpNegotiate_Release
,
287 HttpNegotiate_BeginningTransaction
,
288 HttpNegotiate_OnResponse
291 static IBindStatusCallback
*create_callback(WebBrowser
*This
, PBYTE post_data
,
292 ULONG post_data_len
, LPWSTR headers
, VARIANT_BOOL
*cancel
)
294 BindStatusCallback
*ret
= HeapAlloc(GetProcessHeap(), 0, sizeof(BindStatusCallback
));
296 ret
->lpBindStatusCallbackVtbl
= &BindStatusCallbackVtbl
;
297 ret
->lpHttpNegotiateVtbl
= &HttpNegotiateVtbl
;
300 ret
->post_data
= NULL
;
301 ret
->post_data_len
= post_data_len
;
305 ret
->post_data
= GlobalAlloc(0, post_data_len
);
306 memcpy(ret
->post_data
, post_data
, post_data_len
);
310 int size
= (strlenW(headers
)+1)*sizeof(WCHAR
);
311 ret
->headers
= HeapAlloc(GetProcessHeap(), 0, size
);
312 memcpy(ret
->headers
, headers
, size
);
318 static void on_before_navigate2(WebBrowser
*This
, LPWSTR url
, PBYTE post_data
, ULONG post_data_len
,
319 LPWSTR headers
, VARIANT_BOOL
*cancel
)
321 VARIANT var_url
, var_flags
, var_frame_name
, var_post_data
, var_post_data2
, var_headers
;
322 DISPPARAMS dispparams
;
323 VARIANTARG params
[7];
325 dispparams
.cArgs
= 7;
326 dispparams
.cNamedArgs
= 0;
327 dispparams
.rgdispidNamedArgs
= NULL
;
328 dispparams
.rgvarg
= params
;
330 V_VT(params
) = VT_BOOL
|VT_BYREF
;
331 V_BOOLREF(params
) = cancel
;
333 V_VT(params
+1) = (VT_BYREF
|VT_VARIANT
);
334 V_VARIANTREF(params
+1) = &var_headers
;
335 V_VT(&var_headers
) = VT_BSTR
;
336 V_BSTR(&var_headers
) = headers
;
338 V_VT(params
+2) = (VT_BYREF
|VT_VARIANT
);
339 V_VARIANTREF(params
+2) = &var_post_data2
;
340 V_VT(&var_post_data2
) = (VT_BYREF
|VT_VARIANT
);
341 V_VARIANTREF(&var_post_data2
) = &var_post_data
;
342 VariantInit(&var_post_data
);
345 SAFEARRAYBOUND bound
= {post_data_len
, 0};
348 V_VT(&var_post_data
) = VT_UI1
|VT_ARRAY
;
349 V_ARRAY(&var_post_data
) = SafeArrayCreate(VT_UI1
, 1, &bound
);
351 SafeArrayAccessData(V_ARRAY(&var_post_data
), &data
);
352 memcpy(data
, post_data
, post_data_len
);
353 SafeArrayUnaccessData(V_ARRAY(&var_post_data
));
356 V_VT(params
+3) = (VT_BYREF
|VT_VARIANT
);
357 V_VARIANTREF(params
+3) = &var_frame_name
;
358 V_VT(&var_frame_name
) = VT_BSTR
;
359 V_BSTR(&var_frame_name
) = NULL
;
361 V_VT(params
+4) = (VT_BYREF
|VT_VARIANT
);
362 V_VARIANTREF(params
+4) = &var_flags
;
363 V_VT(&var_flags
) = VT_I4
;
364 V_I4(&var_flags
) = 0;
366 V_VT(params
+5) = (VT_BYREF
|VT_VARIANT
);
367 V_VARIANTREF(params
+5) = &var_url
;
368 V_VT(&var_url
) = VT_BSTR
;
369 V_BSTR(&var_url
) = SysAllocString(url
);
371 V_VT(params
+6) = (VT_DISPATCH
);
372 V_DISPATCH(params
+6) = (IDispatch
*)WEBBROWSER2(This
);
374 call_sink(This
->doc_host
.cp_wbe2
, DISPID_BEFORENAVIGATE2
, &dispparams
);
376 SysFreeString(V_BSTR(&var_url
));
378 SafeArrayDestroy(V_ARRAY(&var_post_data
));
381 static HRESULT
navigate(WebBrowser
*This
, IMoniker
*mon
, IBindCtx
*bindctx
,
382 IBindStatusCallback
*callback
)
385 IPersistMoniker
*persist
;
386 VARIANT_BOOL cancel
= VARIANT_FALSE
;
394 IBindCtx_RegisterObjectParam(bindctx
, (LPOLESTR
)SZ_HTML_CLIENTSITE_OBJECTPARAM
,
395 (IUnknown
*)CLIENTSITE(&This
->doc_host
));
399 * We should use URLMoniker's BindToObject instead creating HTMLDocument here.
400 * This should be fixed when mshtml.dll and urlmon.dll will be good enough.
403 if(This
->doc_host
.document
)
404 deactivate_document(&This
->doc_host
);
406 hres
= CoCreateInstance(&CLSID_HTMLDocument
, NULL
,
407 CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
408 &IID_IUnknown
, (void**)&This
->doc_host
.document
);
411 ERR("Could not create HTMLDocument: %08lx\n", hres
);
415 hres
= IUnknown_QueryInterface(This
->doc_host
.document
, &IID_IPersistMoniker
, (void**)&persist
);
420 IPersistMoniker_Release(persist
);
424 hres
= IPersistMoniker_Load(persist
, FALSE
, mon
, bindctx
, 0);
425 IPersistMoniker_Release(persist
);
427 WARN("Load failed: %08lx\n", hres
);
431 hres
= IUnknown_QueryInterface(This
->doc_host
.document
, &IID_IOleObject
, (void**)&oleobj
);
435 hres
= IOleObject_SetClientSite(oleobj
, CLIENTSITE(&This
->doc_host
));
436 IOleObject_Release(oleobj
);
438 PostMessageW(This
->doc_host
.hwnd
, WB_WM_NAVIGATE2
, 0, 0);
444 HRESULT
navigate_url(WebBrowser
*This
, LPCWSTR url
, PBYTE post_data
, ULONG post_data_len
,
447 IBindStatusCallback
*callback
;
450 VARIANT_BOOL cancel
= VARIANT_FALSE
;
453 hres
= CreateURLMoniker(NULL
, url
, &mon
);
455 WARN("CreateURLMoniker failed: %08lx\n", hres
);
459 IMoniker_GetDisplayName(mon
, NULL
, NULL
, &This
->doc_host
.url
);
460 TRACE("navigating to %s\n", debugstr_w(This
->doc_host
.url
));
462 callback
= create_callback(This
, post_data
, post_data_len
, (LPWSTR
)headers
, &cancel
);
463 CreateAsyncBindCtx(0, callback
, 0, &bindctx
);
465 hres
= navigate(This
, mon
, bindctx
, callback
);
467 IMoniker_Release(mon
);
472 HRESULT
navigate_hlink(WebBrowser
*This
, IMoniker
*mon
, IBindCtx
*bindctx
,
473 IBindStatusCallback
*callback
)
475 IHttpNegotiate
*http_negotiate
;
477 PBYTE post_data
= NULL
;
478 ULONG post_data_len
= 0;
479 LPWSTR headers
= NULL
;
480 VARIANT_BOOL cancel
= VARIANT_FALSE
;
485 IMoniker_GetDisplayName(mon
, NULL
, NULL
, &url
);
486 TRACE("navigating to %s\n", debugstr_w(url
));
488 hres
= IBindStatusCallback_QueryInterface(callback
, &IID_IHttpNegotiate
,
489 (void**)&http_negotiate
);
490 if(SUCCEEDED(hres
)) {
491 static const WCHAR null_string
[] = {0};
493 IHttpNegotiate_BeginningTransaction(http_negotiate
, null_string
, null_string
, 0,
495 IHttpNegotiate_Release(http_negotiate
);
498 memset(&bindinfo
, 0, sizeof(bindinfo
));
499 bindinfo
.cbSize
= sizeof(bindinfo
);
501 hres
= IBindStatusCallback_GetBindInfo(callback
, &bindf
, &bindinfo
);
502 dump_BINDINFO(&bindinfo
);
503 if(bindinfo
.dwBindVerb
== BINDVERB_POST
) {
504 post_data_len
= bindinfo
.cbStgmedData
;
506 post_data
= bindinfo
.stgmedData
.u
.hGlobal
;
509 on_before_navigate2(This
, url
, post_data
, post_data_len
, headers
, &cancel
);
511 CoTaskMemFree(headers
);
512 ReleaseBindInfo(&bindinfo
);
515 FIXME("navigation canceled\n");
520 This
->doc_host
.url
= url
;
522 return navigate(This
, mon
, bindctx
, callback
);
525 #define HLINKFRAME_THIS(iface) DEFINE_THIS(WebBrowser, HlinkFrame, iface)
527 static HRESULT WINAPI
HlinkFrame_QueryInterface(IHlinkFrame
*iface
, REFIID riid
, void **ppv
)
529 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
530 return IWebBrowser2_QueryInterface(WEBBROWSER2(This
), riid
, ppv
);
533 static ULONG WINAPI
HlinkFrame_AddRef(IHlinkFrame
*iface
)
535 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
536 return IWebBrowser2_AddRef(WEBBROWSER2(This
));
539 static ULONG WINAPI
HlinkFrame_Release(IHlinkFrame
*iface
)
541 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
542 return IWebBrowser2_Release(WEBBROWSER2(This
));
545 static HRESULT WINAPI
HlinkFrame_SetBrowseContext(IHlinkFrame
*iface
,
546 IHlinkBrowseContext
*pihlbc
)
548 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
549 FIXME("(%p)->(%p)\n", This
, pihlbc
);
553 static HRESULT WINAPI
HlinkFrame_GetBrowseContext(IHlinkFrame
*iface
,
554 IHlinkBrowseContext
**ppihlbc
)
556 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
557 FIXME("(%p)->(%p)\n", This
, ppihlbc
);
561 static HRESULT WINAPI
HlinkFrame_Navigate(IHlinkFrame
*iface
, DWORD grfHLNF
, LPBC pbc
,
562 IBindStatusCallback
*pibsc
, IHlink
*pihlNavigate
)
564 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
566 LPWSTR location
= NULL
;
568 TRACE("(%p)->(%08lx %p %p %p)\n", This
, grfHLNF
, pbc
, pibsc
, pihlNavigate
);
571 FIXME("unsupported grfHLNF=%08lx\n", grfHLNF
);
573 /* Windows calls GetTargetFrameName here. */
575 IHlink_GetMonikerReference(pihlNavigate
, 1, &mon
, &location
);
578 FIXME("location = %s\n", debugstr_w(location
));
579 CoTaskMemFree(location
);
582 /* Windows calls GetHlinkSite here */
584 if(grfHLNF
& HLNF_OPENINNEWWINDOW
) {
585 FIXME("Not supported HLNF_OPENINNEWWINDOW\n");
589 return navigate_hlink(This
, mon
, pbc
, pibsc
);
592 static HRESULT WINAPI
HlinkFrame_OnNavigate(IHlinkFrame
*iface
, DWORD grfHLNF
,
593 IMoniker
*pimkTarget
, LPCWSTR pwzLocation
, LPCWSTR pwzFriendlyName
, DWORD dwreserved
)
595 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
596 FIXME("(%p)->(%08lx %p %s %s %ld)\n", This
, grfHLNF
, pimkTarget
, debugstr_w(pwzLocation
),
597 debugstr_w(pwzFriendlyName
), dwreserved
);
601 static HRESULT WINAPI
HlinkFrame_UpdateHlink(IHlinkFrame
*iface
, ULONG uHLID
,
602 IMoniker
*pimkTarget
, LPCWSTR pwzLocation
, LPCWSTR pwzFriendlyName
)
604 WebBrowser
*This
= HLINKFRAME_THIS(iface
);
605 FIXME("(%p)->(%lu %p %s %s)\n", This
, uHLID
, pimkTarget
, debugstr_w(pwzLocation
),
606 debugstr_w(pwzFriendlyName
));
610 #undef HLINKFRAME_THIS
612 static const IHlinkFrameVtbl HlinkFrameVtbl
= {
613 HlinkFrame_QueryInterface
,
616 HlinkFrame_SetBrowseContext
,
617 HlinkFrame_GetBrowseContext
,
619 HlinkFrame_OnNavigate
,
620 HlinkFrame_UpdateHlink
623 void WebBrowser_HlinkFrame_Init(WebBrowser
*This
)
625 This
->lpHlinkFrameVtbl
= &HlinkFrameVtbl
;