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->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.
404 deactivate_document(This);
406 hres = CoCreateInstance(&CLSID_HTMLDocument, NULL,
407 CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
408 &IID_IUnknown, (void**)&This->document);
411 ERR("Could not create HTMLDocument: %08lx\n", hres);
415 hres = IUnknown_QueryInterface(This->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->document, &IID_IOleObject, (void**)&oleobj);
435 hres = IOleObject_SetClientSite(oleobj, CLIENTSITE(&This->doc_host));
436 IOleObject_Release(oleobj);
438 PostMessageW(This->doc_view_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->url);
460 TRACE("navigating to %s\n", debugstr_w(This->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");
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;