winemac: Add the ability to disable high-resolution scrolling.
[wine/multimedia.git] / dlls / ieframe / navigate.c
blob886fa014a896a5b484c41728a4d1757734a68c9c
1 /*
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 "ieframe.h"
24 #include "exdispid.h"
25 #include "shellapi.h"
26 #include "winreg.h"
27 #include "shlwapi.h"
28 #include "wininet.h"
29 #include "mshtml.h"
30 #include "perhist.h"
31 #include "resource.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(ieframe);
37 static const WCHAR emptyW[] = {0};
39 typedef struct {
40 IBindStatusCallback IBindStatusCallback_iface;
41 IHttpNegotiate IHttpNegotiate_iface;
42 IHttpSecurity IHttpSecurity_iface;
44 LONG ref;
46 DocHost *doc_host;
47 IBinding *binding;
49 BSTR url;
50 HGLOBAL post_data;
51 BSTR headers;
52 ULONG post_data_len;
53 } BindStatusCallback;
55 static void dump_BINDINFO(BINDINFO *bi)
57 static const char * const BINDINFOF_str[] = {
58 "#0",
59 "BINDINFOF_URLENCODESTGMEDDATA",
60 "BINDINFOF_URLENCODEDEXTRAINFO"
63 static const char * const BINDVERB_str[] = {
64 "BINDVERB_GET",
65 "BINDVERB_POST",
66 "BINDVERB_PUT",
67 "BINDVERB_CUSTOM"
70 TRACE("\n"
71 "BINDINFO = {\n"
72 " %d, %s,\n"
73 " {%d, %p, %p},\n"
74 " %s,\n"
75 " %s,\n"
76 " %s,\n"
77 " %d, %08x, %d, %d\n"
78 " {%d %p %x},\n"
79 " %s\n"
80 " %p, %d\n"
81 "}\n",
83 bi->cbSize, debugstr_w(bi->szExtraInfo),
84 bi->stgmedData.tymed, bi->stgmedData.u.hGlobal, bi->stgmedData.pUnkForRelease,
85 bi->grfBindInfoF > BINDINFOF_URLENCODEDEXTRAINFO
86 ? "unknown" : BINDINFOF_str[bi->grfBindInfoF],
87 bi->dwBindVerb > BINDVERB_CUSTOM
88 ? "unknown" : BINDVERB_str[bi->dwBindVerb],
89 debugstr_w(bi->szCustomVerb),
90 bi->cbstgmedData, bi->dwOptions, bi->dwOptionsFlags, bi->dwCodePage,
91 bi->securityAttributes.nLength,
92 bi->securityAttributes.lpSecurityDescriptor,
93 bi->securityAttributes.bInheritHandle,
94 debugstr_guid(&bi->iid),
95 bi->pUnk, bi->dwReserved
99 static void set_status_text(BindStatusCallback *This, ULONG statuscode, LPCWSTR str)
101 VARIANTARG arg;
102 DISPPARAMS dispparams = {&arg, NULL, 1, 0};
103 WCHAR fmt[IDS_STATUSFMT_MAXLEN];
104 WCHAR buffer[IDS_STATUSFMT_MAXLEN + INTERNET_MAX_URL_LENGTH];
106 if(!This->doc_host)
107 return;
109 TRACE("(%p, %d, %s)\n", This, statuscode, debugstr_w(str));
110 buffer[0] = 0;
111 if (statuscode && str && *str) {
112 fmt[0] = 0;
113 /* the format string must have one "%s" for the str */
114 LoadStringW(ieframe_instance, IDS_STATUSFMT_FIRST + statuscode, fmt, IDS_STATUSFMT_MAXLEN);
115 snprintfW(buffer, sizeof(buffer)/sizeof(WCHAR), fmt, str);
118 V_VT(&arg) = VT_BSTR;
119 V_BSTR(&arg) = str ? SysAllocString(buffer) : NULL;
120 TRACE("=> %s\n", debugstr_w(V_BSTR(&arg)));
122 call_sink(This->doc_host->cps.wbe2, DISPID_STATUSTEXTCHANGE, &dispparams);
124 if(This->doc_host->frame)
125 IOleInPlaceFrame_SetStatusText(This->doc_host->frame, buffer);
127 VariantClear(&arg);
131 HRESULT set_dochost_url(DocHost *This, const WCHAR *url)
133 WCHAR *new_url;
135 if(url) {
136 new_url = heap_strdupW(url);
137 if(!new_url)
138 return E_OUTOFMEMORY;
139 }else {
140 new_url = NULL;
143 heap_free(This->url);
144 This->url = new_url;
146 This->container_vtbl->SetURL(This, This->url);
147 return S_OK;
150 static inline BindStatusCallback *impl_from_IBindStatusCallback(IBindStatusCallback *iface)
152 return CONTAINING_RECORD(iface, BindStatusCallback, IBindStatusCallback_iface);
155 static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *iface,
156 REFIID riid, void **ppv)
158 BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
160 if(IsEqualGUID(&IID_IUnknown, riid)) {
161 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
162 *ppv = &This->IBindStatusCallback_iface;
163 }else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) {
164 TRACE("(%p)->(IID_IBindStatusCallback %p)\n", This, ppv);
165 *ppv = &This->IBindStatusCallback_iface;
166 }else if(IsEqualGUID(&IID_IHttpNegotiate, riid)) {
167 TRACE("(%p)->(IID_IHttpNegotiate %p)\n", This, ppv);
168 *ppv = &This->IHttpNegotiate_iface;
169 }else if(IsEqualGUID(&IID_IWindowForBindingUI, riid)) {
170 TRACE("(%p)->(IID_IWindowForBindingUI %p)\n", This, ppv);
171 *ppv = &This->IHttpSecurity_iface;
172 }else if(IsEqualGUID(&IID_IHttpSecurity, riid)) {
173 TRACE("(%p)->(IID_IHttpSecurity %p)\n", This, ppv);
174 *ppv = &This->IHttpSecurity_iface;
175 }else {
176 *ppv = NULL;
177 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
178 return E_NOINTERFACE;
181 IUnknown_AddRef((IUnknown*)*ppv);
182 return S_OK;
185 static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface)
187 BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
188 LONG ref = InterlockedIncrement(&This->ref);
190 TRACE("(%p) ref=%d\n", This, ref);
192 return ref;
195 static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface)
197 BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
198 LONG ref = InterlockedDecrement(&This->ref);
200 TRACE("(%p) ref=%d\n", This, ref);
202 if(!ref) {
203 if(This->doc_host)
204 IOleClientSite_Release(&This->doc_host->IOleClientSite_iface);
205 if(This->binding)
206 IBinding_Release(This->binding);
207 if(This->post_data)
208 GlobalFree(This->post_data);
209 SysFreeString(This->headers);
210 SysFreeString(This->url);
211 heap_free(This);
214 return ref;
217 static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface,
218 DWORD dwReserved, IBinding *pbind)
220 BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
222 TRACE("(%p)->(%d %p)\n", This, dwReserved, pbind);
224 This->binding = pbind;
225 IBinding_AddRef(This->binding);
227 return S_OK;
230 static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface,
231 LONG *pnPriority)
233 BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
234 FIXME("(%p)->(%p)\n", This, pnPriority);
235 return E_NOTIMPL;
238 static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallback *iface,
239 DWORD reserved)
241 BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
242 FIXME("(%p)->(%d)\n", This, reserved);
243 return E_NOTIMPL;
246 static DWORD get_http_status_code(IBinding *binding)
248 IWinInetHttpInfo *http_info;
249 DWORD status, size = sizeof(DWORD);
250 HRESULT hres;
252 hres = IBinding_QueryInterface(binding, &IID_IWinInetHttpInfo, (void**)&http_info);
253 if(FAILED(hres))
254 return HTTP_STATUS_OK;
256 hres = IWinInetHttpInfo_QueryInfo(http_info, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER,
257 &status, &size, NULL, NULL);
258 IWinInetHttpInfo_Release(http_info);
260 if(FAILED(hres))
261 return HTTP_STATUS_OK;
262 return status;
265 static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface,
266 ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
268 BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
269 DWORD status_code;
271 TRACE("(%p)->(%d %d %d %s)\n", This, ulProgress, ulProgressMax, ulStatusCode,
272 debugstr_w(szStatusText));
274 switch(ulStatusCode) {
275 case BINDSTATUS_REDIRECTING:
276 return set_dochost_url(This->doc_host, szStatusText);
277 case BINDSTATUS_BEGINDOWNLOADDATA:
278 set_status_text(This, ulStatusCode, szStatusText);
279 status_code = get_http_status_code(This->binding);
280 if(status_code != HTTP_STATUS_OK)
281 handle_navigation_error(This->doc_host, status_code, This->url, NULL);
282 return S_OK;
284 case BINDSTATUS_FINDINGRESOURCE:
285 case BINDSTATUS_ENDDOWNLOADDATA:
286 case BINDSTATUS_SENDINGREQUEST:
287 set_status_text(This, ulStatusCode, szStatusText);
288 return S_OK;
290 case BINDSTATUS_CONNECTING:
291 case BINDSTATUS_CACHEFILENAMEAVAILABLE:
292 case BINDSTATUS_CLASSIDAVAILABLE:
293 case BINDSTATUS_MIMETYPEAVAILABLE:
294 case BINDSTATUS_BEGINSYNCOPERATION:
295 case BINDSTATUS_ENDSYNCOPERATION:
296 return S_OK;
297 default:
298 FIXME("status code %u\n", ulStatusCode);
301 return S_OK;
304 void handle_navigation_error(DocHost* doc_host, HRESULT hres, BSTR url, IHTMLWindow2 *win2)
306 VARIANT var_status_code, var_frame_name, var_url;
307 DISPPARAMS dispparams;
308 VARIANTARG params[5];
309 VARIANT_BOOL cancel = VARIANT_FALSE;
311 dispparams.cArgs = 5;
312 dispparams.cNamedArgs = 0;
313 dispparams.rgdispidNamedArgs = NULL;
314 dispparams.rgvarg = params;
316 V_VT(params) = VT_BOOL|VT_BYREF;
317 V_BOOLREF(params) = &cancel;
319 V_VT(params+1) = VT_VARIANT|VT_BYREF;
320 V_VARIANTREF(params+1) = &var_status_code;
321 V_VT(&var_status_code) = VT_I4;
322 V_I4(&var_status_code) = hres;
324 V_VT(params+2) = VT_VARIANT|VT_BYREF;
325 V_VARIANTREF(params+2) = &var_frame_name;
326 V_VT(&var_frame_name) = VT_BSTR;
327 if(win2) {
328 hres = IHTMLWindow2_get_name(win2, &V_BSTR(&var_frame_name));
329 if(FAILED(hres))
330 V_BSTR(&var_frame_name) = NULL;
331 } else
332 V_BSTR(&var_frame_name) = NULL;
334 V_VT(params+3) = VT_VARIANT|VT_BYREF;
335 V_VARIANTREF(params+3) = &var_url;
336 V_VT(&var_url) = VT_BSTR;
337 V_BSTR(&var_url) = url;
339 V_VT(params+4) = VT_DISPATCH;
340 V_DISPATCH(params+4) = (IDispatch*)doc_host->wb;
342 call_sink(doc_host->cps.wbe2, DISPID_NAVIGATEERROR, &dispparams);
343 SysFreeString(V_BSTR(&var_frame_name));
345 if(!cancel)
346 FIXME("Navigate to error page\n");
349 static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface,
350 HRESULT hresult, LPCWSTR szError)
352 BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
354 TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
356 set_status_text(This, 0, emptyW);
358 if(!This->doc_host)
359 return S_OK;
361 if(FAILED(hresult))
362 handle_navigation_error(This->doc_host, hresult, This->url, NULL);
364 IOleClientSite_Release(&This->doc_host->IOleClientSite_iface);
365 This->doc_host = NULL;
367 IBinding_Release(This->binding);
368 This->binding = NULL;
370 return S_OK;
373 static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface,
374 DWORD *grfBINDF, BINDINFO *pbindinfo)
376 BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
378 TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
380 *grfBINDF = BINDF_ASYNCHRONOUS;
382 if(This->post_data) {
383 pbindinfo->dwBindVerb = BINDVERB_POST;
385 pbindinfo->stgmedData.tymed = TYMED_HGLOBAL;
386 pbindinfo->stgmedData.u.hGlobal = This->post_data;
387 pbindinfo->cbstgmedData = This->post_data_len;
388 pbindinfo->stgmedData.pUnkForRelease = (IUnknown*)&This->IBindStatusCallback_iface;
389 IBindStatusCallback_AddRef(&This->IBindStatusCallback_iface);
392 return S_OK;
395 static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *iface,
396 DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed)
398 BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
399 FIXME("(%p)->(%08x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
400 return E_NOTIMPL;
403 static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface,
404 REFIID riid, IUnknown *punk)
406 BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
408 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), punk);
410 return dochost_object_available(This->doc_host, punk);
413 static const IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
414 BindStatusCallback_QueryInterface,
415 BindStatusCallback_AddRef,
416 BindStatusCallback_Release,
417 BindStatusCallback_OnStartBinding,
418 BindStatusCallback_GetPriority,
419 BindStatusCallback_OnLowResource,
420 BindStatusCallback_OnProgress,
421 BindStatusCallback_OnStopBinding,
422 BindStatusCallback_GetBindInfo,
423 BindStatusCallback_OnDataAvailable,
424 BindStatusCallback_OnObjectAvailable
427 static inline BindStatusCallback *impl_from_IHttpNegotiate(IHttpNegotiate *iface)
429 return CONTAINING_RECORD(iface, BindStatusCallback, IHttpNegotiate_iface);
432 static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate *iface,
433 REFIID riid, void **ppv)
435 BindStatusCallback *This = impl_from_IHttpNegotiate(iface);
436 return IBindStatusCallback_QueryInterface(&This->IBindStatusCallback_iface, riid, ppv);
439 static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate *iface)
441 BindStatusCallback *This = impl_from_IHttpNegotiate(iface);
442 return IBindStatusCallback_AddRef(&This->IBindStatusCallback_iface);
445 static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate *iface)
447 BindStatusCallback *This = impl_from_IHttpNegotiate(iface);
448 return IBindStatusCallback_Release(&This->IBindStatusCallback_iface);
451 static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate *iface,
452 LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
454 BindStatusCallback *This = impl_from_IHttpNegotiate(iface);
456 TRACE("(%p)->(%s %s %d %p)\n", This, debugstr_w(szURL), debugstr_w(szHeaders),
457 dwReserved, pszAdditionalHeaders);
459 if(This->headers) {
460 int size = (strlenW(This->headers)+1)*sizeof(WCHAR);
461 *pszAdditionalHeaders = CoTaskMemAlloc(size);
462 memcpy(*pszAdditionalHeaders, This->headers, size);
465 return S_OK;
468 static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate *iface,
469 DWORD dwResponseCode, LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders,
470 LPWSTR *pszAdditionalRequestHeaders)
472 BindStatusCallback *This = impl_from_IHttpNegotiate(iface);
473 TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders),
474 debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders);
475 return S_OK;
478 static const IHttpNegotiateVtbl HttpNegotiateVtbl = {
479 HttpNegotiate_QueryInterface,
480 HttpNegotiate_AddRef,
481 HttpNegotiate_Release,
482 HttpNegotiate_BeginningTransaction,
483 HttpNegotiate_OnResponse
486 static inline BindStatusCallback *impl_from_IHttpSecurity(IHttpSecurity *iface)
488 return CONTAINING_RECORD(iface, BindStatusCallback, IHttpSecurity_iface);
491 static HRESULT WINAPI HttpSecurity_QueryInterface(IHttpSecurity *iface, REFIID riid, void **ppv)
493 BindStatusCallback *This = impl_from_IHttpSecurity(iface);
494 return IBindStatusCallback_QueryInterface(&This->IBindStatusCallback_iface, riid, ppv);
497 static ULONG WINAPI HttpSecurity_AddRef(IHttpSecurity *iface)
499 BindStatusCallback *This = impl_from_IHttpSecurity(iface);
500 return IBindStatusCallback_AddRef(&This->IBindStatusCallback_iface);
503 static ULONG WINAPI HttpSecurity_Release(IHttpSecurity *iface)
505 BindStatusCallback *This = impl_from_IHttpSecurity(iface);
506 return IBindStatusCallback_Release(&This->IBindStatusCallback_iface);
509 static HRESULT WINAPI HttpSecurity_GetWindow(IHttpSecurity *iface, REFGUID rguidReason, HWND *phwnd)
511 BindStatusCallback *This = impl_from_IHttpSecurity(iface);
513 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(rguidReason), phwnd);
515 if(!This->doc_host)
516 return E_FAIL;
518 *phwnd = This->doc_host->frame_hwnd;
519 return S_OK;
522 static HRESULT WINAPI HttpSecurity_OnSecurityProblem(IHttpSecurity *iface, DWORD dwProblem)
524 BindStatusCallback *This = impl_from_IHttpSecurity(iface);
525 FIXME("(%p)->(%u)\n", This, dwProblem);
526 return S_FALSE;
529 static const IHttpSecurityVtbl HttpSecurityVtbl = {
530 HttpSecurity_QueryInterface,
531 HttpSecurity_AddRef,
532 HttpSecurity_Release,
533 HttpSecurity_GetWindow,
534 HttpSecurity_OnSecurityProblem
537 static BindStatusCallback *create_callback(DocHost *doc_host, LPCWSTR url, PBYTE post_data,
538 ULONG post_data_len, LPCWSTR headers)
540 BindStatusCallback *ret = heap_alloc(sizeof(BindStatusCallback));
542 ret->IBindStatusCallback_iface.lpVtbl = &BindStatusCallbackVtbl;
543 ret->IHttpNegotiate_iface.lpVtbl = &HttpNegotiateVtbl;
544 ret->IHttpSecurity_iface.lpVtbl = &HttpSecurityVtbl;
546 ret->ref = 1;
547 ret->url = SysAllocString(url);
548 ret->post_data = NULL;
549 ret->post_data_len = post_data_len;
550 ret->headers = headers ? SysAllocString(headers) : NULL;
552 ret->doc_host = doc_host;
553 IOleClientSite_AddRef(&doc_host->IOleClientSite_iface);
555 ret->binding = NULL;
557 if(post_data) {
558 ret->post_data = GlobalAlloc(0, post_data_len);
559 memcpy(ret->post_data, post_data, post_data_len);
562 return ret;
565 static void on_before_navigate2(DocHost *This, LPCWSTR url, SAFEARRAY *post_data, LPWSTR headers, VARIANT_BOOL *cancel)
567 VARIANT var_url, var_flags, var_frame_name, var_post_data, var_post_data2, var_headers;
568 DISPPARAMS dispparams;
569 VARIANTARG params[7];
570 WCHAR file_path[MAX_PATH];
571 DWORD file_path_len = sizeof(file_path) / sizeof(*file_path);
573 dispparams.cArgs = 7;
574 dispparams.cNamedArgs = 0;
575 dispparams.rgdispidNamedArgs = NULL;
576 dispparams.rgvarg = params;
578 This->busy = VARIANT_TRUE;
580 V_VT(params) = VT_BOOL|VT_BYREF;
581 V_BOOLREF(params) = cancel;
583 V_VT(params+1) = (VT_BYREF|VT_VARIANT);
584 V_VARIANTREF(params+1) = &var_headers;
585 V_VT(&var_headers) = VT_BSTR;
586 V_BSTR(&var_headers) = headers;
588 V_VT(params+2) = (VT_BYREF|VT_VARIANT);
589 V_VARIANTREF(params+2) = &var_post_data2;
590 V_VT(&var_post_data2) = (VT_BYREF|VT_VARIANT);
591 V_VARIANTREF(&var_post_data2) = &var_post_data;
593 if(post_data) {
594 V_VT(&var_post_data) = VT_UI1|VT_ARRAY;
595 V_ARRAY(&var_post_data) = post_data;
596 }else {
597 V_VT(&var_post_data) = VT_EMPTY;
600 V_VT(params+3) = (VT_BYREF|VT_VARIANT);
601 V_VARIANTREF(params+3) = &var_frame_name;
602 V_VT(&var_frame_name) = VT_BSTR;
603 V_BSTR(&var_frame_name) = NULL;
605 V_VT(params+4) = (VT_BYREF|VT_VARIANT);
606 V_VARIANTREF(params+4) = &var_flags;
607 V_VT(&var_flags) = VT_I4;
608 V_I4(&var_flags) = 0;
610 V_VT(params+5) = (VT_BYREF|VT_VARIANT);
611 V_VARIANTREF(params+5) = &var_url;
612 V_VT(&var_url) = VT_BSTR;
613 if(PathCreateFromUrlW(url, file_path, &file_path_len, 0) == S_OK)
614 V_BSTR(&var_url) = SysAllocString(file_path);
615 else
616 V_BSTR(&var_url) = SysAllocString(url);
618 V_VT(params+6) = (VT_DISPATCH);
619 V_DISPATCH(params+6) = (IDispatch*)This->wb;
621 call_sink(This->cps.wbe2, DISPID_BEFORENAVIGATE2, &dispparams);
623 SysFreeString(V_BSTR(&var_url));
626 /* FIXME: urlmon should handle it */
627 static BOOL try_application_url(LPCWSTR url)
629 SHELLEXECUTEINFOW exec_info;
630 WCHAR app[64];
631 HKEY hkey;
632 DWORD res, type;
633 HRESULT hres;
635 static const WCHAR wszURLProtocol[] = {'U','R','L',' ','P','r','o','t','o','c','o','l',0};
637 hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, app, sizeof(app)/sizeof(WCHAR), NULL, 0);
638 if(FAILED(hres))
639 return FALSE;
641 res = RegOpenKeyW(HKEY_CLASSES_ROOT, app, &hkey);
642 if(res != ERROR_SUCCESS)
643 return FALSE;
645 res = RegQueryValueExW(hkey, wszURLProtocol, NULL, &type, NULL, NULL);
646 RegCloseKey(hkey);
647 if(res != ERROR_SUCCESS || type != REG_SZ)
648 return FALSE;
650 TRACE("opening application %s\n", debugstr_w(app));
652 memset(&exec_info, 0, sizeof(exec_info));
653 exec_info.cbSize = sizeof(exec_info);
654 exec_info.lpFile = url;
655 exec_info.nShow = SW_SHOW;
657 return ShellExecuteExW(&exec_info);
660 static HRESULT create_moniker(LPCWSTR url, IMoniker **mon)
662 WCHAR new_url[INTERNET_MAX_URL_LENGTH];
663 DWORD size;
664 HRESULT hres;
666 if(PathIsURLW(url))
667 return CreateURLMoniker(NULL, url, mon);
669 size = sizeof(new_url)/sizeof(WCHAR);
670 hres = UrlApplySchemeW(url, new_url, &size, URL_APPLY_GUESSSCHEME | URL_APPLY_GUESSFILE);
671 TRACE("was %s got %s\n", debugstr_w(url), debugstr_w(new_url));
672 if(FAILED(hres)) {
673 WARN("UrlApplyScheme failed: %08x\n", hres);
674 return hres;
677 return CreateURLMoniker(NULL, new_url, mon);
680 static HRESULT bind_to_object(DocHost *This, IMoniker *mon, LPCWSTR url, IBindCtx *bindctx,
681 IBindStatusCallback *callback)
683 IUnknown *unk = NULL;
684 WCHAR *display_name;
685 HRESULT hres;
687 if(mon) {
688 IMoniker_AddRef(mon);
689 }else {
690 hres = create_moniker(url, &mon);
691 if(FAILED(hres))
692 return hres;
695 hres = IMoniker_GetDisplayName(mon, 0, NULL, &display_name);
696 if(FAILED(hres)) {
697 FIXME("GetDisplayName failed: %08x\n", hres);
698 return hres;
701 hres = set_dochost_url(This, display_name);
702 CoTaskMemFree(display_name);
703 if(FAILED(hres))
704 return hres;
706 IBindCtx_RegisterObjectParam(bindctx, (LPOLESTR)SZ_HTML_CLIENTSITE_OBJECTPARAM,
707 (IUnknown*)&This->IOleClientSite_iface);
709 hres = IMoniker_BindToObject(mon, bindctx, NULL, &IID_IUnknown, (void**)&unk);
710 if(SUCCEEDED(hres)) {
711 hres = S_OK;
712 if(unk)
713 IUnknown_Release(unk);
714 }else if(try_application_url(url)) {
715 hres = S_OK;
716 }else {
717 FIXME("BindToObject failed: %08x\n", hres);
720 IMoniker_Release(mon);
721 return S_OK;
724 static void html_window_navigate(DocHost *This, IHTMLPrivateWindow *window, BSTR url, BSTR headers, SAFEARRAY *post_data)
726 VARIANT headers_var, post_data_var;
727 BSTR empty_str;
728 HRESULT hres;
730 hres = set_dochost_url(This, url);
731 if(FAILED(hres))
732 return;
734 empty_str = SysAllocStringLen(NULL, 0);
736 if(headers) {
737 V_VT(&headers_var) = VT_BSTR;
738 V_BSTR(&headers_var) = headers;
739 }else {
740 V_VT(&headers_var) = VT_EMPTY;
743 if(post_data) {
744 V_VT(&post_data_var) = VT_UI1|VT_ARRAY;
745 V_ARRAY(&post_data_var) = post_data;
746 }else {
747 V_VT(&post_data_var) = VT_EMPTY;
750 set_doc_state(This, READYSTATE_LOADING);
751 hres = IHTMLPrivateWindow_SuperNavigate(window, url, empty_str, NULL, NULL, &post_data_var, &headers_var, 0);
752 SysFreeString(empty_str);
753 if(FAILED(hres))
754 WARN("SuprtNavigate failed: %08x\n", hres);
757 typedef struct {
758 task_header_t header;
759 BSTR url;
760 BSTR headers;
761 SAFEARRAY *post_data;
762 BOOL async_notif;
763 } task_doc_navigate_t;
765 static void doc_navigate_task_destr(task_header_t *t)
767 task_doc_navigate_t *task = (task_doc_navigate_t*)t;
769 SysFreeString(task->url);
770 SysFreeString(task->headers);
771 if(task->post_data)
772 SafeArrayDestroy(task->post_data);
773 heap_free(task);
776 static void doc_navigate_proc(DocHost *This, task_header_t *t)
778 task_doc_navigate_t *task = (task_doc_navigate_t*)t;
779 IHTMLPrivateWindow *priv_window;
780 HRESULT hres;
782 if(!This->doc_navigate) {
783 ERR("Skip nav\n");
784 return;
787 if(task->async_notif) {
788 VARIANT_BOOL cancel = VARIANT_FALSE;
789 on_before_navigate2(This, task->url, task->post_data, task->headers, &cancel);
790 if(cancel) {
791 TRACE("Navigation canceled\n");
792 return;
796 hres = IUnknown_QueryInterface(This->doc_navigate, &IID_IHTMLPrivateWindow, (void**)&priv_window);
797 if(SUCCEEDED(hres)) {
798 html_window_navigate(This, priv_window, task->url, task->headers, task->post_data);
799 IHTMLPrivateWindow_Release(priv_window);
800 }else {
801 WARN("Could not get IHTMLPrivateWindow iface: %08x\n", hres);
805 static HRESULT async_doc_navigate(DocHost *This, LPCWSTR url, LPCWSTR headers, PBYTE post_data, ULONG post_data_size,
806 BOOL async_notif)
808 task_doc_navigate_t *task;
810 TRACE("%s\n", debugstr_w(url));
812 task = heap_alloc_zero(sizeof(*task));
813 if(!task)
814 return E_OUTOFMEMORY;
816 task->url = SysAllocString(url);
817 if(!task->url) {
818 doc_navigate_task_destr(&task->header);
819 return E_OUTOFMEMORY;
822 if(headers) {
823 task->headers = SysAllocString(headers);
824 if(!task->headers) {
825 doc_navigate_task_destr(&task->header);
826 return E_OUTOFMEMORY;
830 if(post_data) {
831 task->post_data = SafeArrayCreateVector(VT_UI1, 0, post_data_size);
832 if(!task->post_data) {
833 doc_navigate_task_destr(&task->header);
834 return E_OUTOFMEMORY;
837 memcpy(task->post_data->pvData, post_data, post_data_size);
840 if(!async_notif) {
841 VARIANT_BOOL cancel = VARIANT_FALSE;
843 on_before_navigate2(This, task->url, task->post_data, task->headers, &cancel);
844 if(cancel) {
845 TRACE("Navigation canceled\n");
846 doc_navigate_task_destr(&task->header);
847 return S_OK;
851 task->async_notif = async_notif;
852 abort_dochost_tasks(This, doc_navigate_proc);
853 push_dochost_task(This, &task->header, doc_navigate_proc, doc_navigate_task_destr, FALSE);
854 return S_OK;
857 static HRESULT navigate_bsc(DocHost *This, BindStatusCallback *bsc, IMoniker *mon)
859 VARIANT_BOOL cancel = VARIANT_FALSE;
860 SAFEARRAY *post_data = NULL;
861 IBindCtx *bindctx;
862 HRESULT hres;
864 set_doc_state(This, READYSTATE_LOADING);
866 if(bsc->post_data) {
867 post_data = SafeArrayCreateVector(VT_UI1, 0, bsc->post_data_len);
868 memcpy(post_data->pvData, post_data, bsc->post_data_len);
871 on_before_navigate2(This, bsc->url, post_data, bsc->headers, &cancel);
872 if(post_data)
873 SafeArrayDestroy(post_data);
874 if(cancel) {
875 FIXME("Navigation canceled\n");
876 return S_OK;
879 if(This->document)
880 deactivate_document(This);
882 CreateAsyncBindCtx(0, &bsc->IBindStatusCallback_iface, 0, &bindctx);
884 if(This->frame)
885 IOleInPlaceFrame_EnableModeless(This->frame, FALSE);
887 hres = bind_to_object(This, mon, bsc->url, bindctx, &bsc->IBindStatusCallback_iface);
889 if(This->frame)
890 IOleInPlaceFrame_EnableModeless(This->frame, TRUE);
892 IBindCtx_Release(bindctx);
894 return hres;
897 typedef struct {
898 task_header_t header;
899 BindStatusCallback *bsc;
900 } task_navigate_bsc_t;
902 static void navigate_bsc_task_destr(task_header_t *t)
904 task_navigate_bsc_t *task = (task_navigate_bsc_t*)t;
906 IBindStatusCallback_Release(&task->bsc->IBindStatusCallback_iface);
907 heap_free(task);
910 static void navigate_bsc_proc(DocHost *This, task_header_t *t)
912 task_navigate_bsc_t *task = (task_navigate_bsc_t*)t;
914 if(!This->hwnd)
915 create_doc_view_hwnd(This);
917 navigate_bsc(This, task->bsc, NULL);
921 HRESULT navigate_url(DocHost *This, LPCWSTR url, const VARIANT *Flags,
922 const VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
924 PBYTE post_data = NULL;
925 ULONG post_data_len = 0;
926 LPWSTR headers = NULL;
927 HRESULT hres = S_OK;
929 TRACE("navigating to %s\n", debugstr_w(url));
931 if((Flags && V_VT(Flags) != VT_EMPTY && V_VT(Flags) != VT_ERROR)
932 || (TargetFrameName && V_VT(TargetFrameName) != VT_EMPTY && V_VT(TargetFrameName) != VT_ERROR))
933 FIXME("Unsupported args (Flags %s; TargetFrameName %s)\n", debugstr_variant(Flags), debugstr_variant(TargetFrameName));
935 if(PostData && V_VT(PostData) == (VT_ARRAY | VT_UI1) && V_ARRAY(PostData)) {
936 SafeArrayAccessData(V_ARRAY(PostData), (void**)&post_data);
937 post_data_len = V_ARRAY(PostData)->rgsabound[0].cElements;
940 if(Headers && V_VT(Headers) == VT_BSTR) {
941 headers = V_BSTR(Headers);
942 TRACE("Headers: %s\n", debugstr_w(headers));
945 set_doc_state(This, READYSTATE_LOADING);
946 This->ready_state = READYSTATE_LOADING;
948 if(This->doc_navigate) {
949 WCHAR new_url[INTERNET_MAX_URL_LENGTH];
951 if(PathIsURLW(url)) {
952 new_url[0] = 0;
953 }else {
954 DWORD size;
956 size = sizeof(new_url)/sizeof(WCHAR);
957 hres = UrlApplySchemeW(url, new_url, &size,
958 URL_APPLY_GUESSSCHEME | URL_APPLY_GUESSFILE | URL_APPLY_DEFAULT);
959 if(FAILED(hres)) {
960 WARN("UrlApplyScheme failed: %08x\n", hres);
961 new_url[0] = 0;
965 hres = async_doc_navigate(This, *new_url ? new_url : url, headers, post_data,
966 post_data_len, TRUE);
967 }else {
968 task_navigate_bsc_t *task;
970 task = heap_alloc(sizeof(*task));
971 task->bsc = create_callback(This, url, post_data, post_data_len, headers);
972 push_dochost_task(This, &task->header, navigate_bsc_proc, navigate_bsc_task_destr, This->url == NULL);
975 if(post_data)
976 SafeArrayUnaccessData(V_ARRAY(PostData));
978 return hres;
981 static HRESULT navigate_hlink(DocHost *This, IMoniker *mon, IBindCtx *bindctx,
982 IBindStatusCallback *callback)
984 IHttpNegotiate *http_negotiate;
985 BindStatusCallback *bsc;
986 PBYTE post_data = NULL;
987 ULONG post_data_len = 0;
988 LPWSTR headers = NULL, url;
989 BINDINFO bindinfo;
990 DWORD bindf = 0;
991 HRESULT hres;
993 TRACE("\n");
995 hres = IMoniker_GetDisplayName(mon, 0, NULL, &url);
996 if(FAILED(hres))
997 FIXME("GetDisplayName failed: %08x\n", hres);
999 hres = IBindStatusCallback_QueryInterface(callback, &IID_IHttpNegotiate,
1000 (void**)&http_negotiate);
1001 if(SUCCEEDED(hres)) {
1002 static const WCHAR null_string[] = {0};
1004 IHttpNegotiate_BeginningTransaction(http_negotiate, null_string, null_string, 0,
1005 &headers);
1006 IHttpNegotiate_Release(http_negotiate);
1009 memset(&bindinfo, 0, sizeof(bindinfo));
1010 bindinfo.cbSize = sizeof(bindinfo);
1012 hres = IBindStatusCallback_GetBindInfo(callback, &bindf, &bindinfo);
1013 dump_BINDINFO(&bindinfo);
1014 if(bindinfo.dwBindVerb == BINDVERB_POST) {
1015 post_data_len = bindinfo.cbstgmedData;
1016 if(post_data_len)
1017 post_data = bindinfo.stgmedData.u.hGlobal;
1020 if(This->doc_navigate) {
1021 hres = async_doc_navigate(This, url, headers, post_data, post_data_len, FALSE);
1022 }else {
1023 bsc = create_callback(This, url, post_data, post_data_len, headers);
1024 hres = navigate_bsc(This, bsc, mon);
1025 IBindStatusCallback_Release(&bsc->IBindStatusCallback_iface);
1028 CoTaskMemFree(url);
1029 CoTaskMemFree(headers);
1030 ReleaseBindInfo(&bindinfo);
1032 return hres;
1035 HRESULT go_home(DocHost *This)
1037 HKEY hkey;
1038 DWORD res, type, size;
1039 WCHAR wszPageName[MAX_PATH];
1040 static const WCHAR wszAboutBlank[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
1041 static const WCHAR wszStartPage[] = {'S','t','a','r','t',' ','P','a','g','e',0};
1042 static const WCHAR wszSubKey[] = {'S','o','f','t','w','a','r','e','\\',
1043 'M','i','c','r','o','s','o','f','t','\\',
1044 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
1045 'M','a','i','n',0};
1047 res = RegOpenKeyW(HKEY_CURRENT_USER, wszSubKey, &hkey);
1048 if (res != ERROR_SUCCESS)
1049 return navigate_url(This, wszAboutBlank, NULL, NULL, NULL, NULL);
1051 size = sizeof(wszPageName);
1052 res = RegQueryValueExW(hkey, wszStartPage, NULL, &type, (LPBYTE)wszPageName, &size);
1053 RegCloseKey(hkey);
1054 if (res != ERROR_SUCCESS || type != REG_SZ)
1055 return navigate_url(This, wszAboutBlank, NULL, NULL, NULL, NULL);
1057 return navigate_url(This, wszPageName, NULL, NULL, NULL, NULL);
1060 static HRESULT navigate_history(DocHost *This, unsigned travellog_pos)
1062 IPersistHistory *persist_history;
1063 travellog_entry_t *entry;
1064 LARGE_INTEGER li;
1065 HRESULT hres;
1067 if(!This->doc_navigate) {
1068 FIXME("unsupported doc_navigate FALSE\n");
1069 return E_NOTIMPL;
1072 This->travellog.loading_pos = travellog_pos;
1073 entry = This->travellog.log + This->travellog.loading_pos;
1075 if(!entry->stream)
1076 return async_doc_navigate(This, entry->url, NULL, NULL, 0, FALSE);
1078 hres = IUnknown_QueryInterface(This->document, &IID_IPersistHistory, (void**)&persist_history);
1079 if(FAILED(hres))
1080 return hres;
1082 li.QuadPart = 0;
1083 IStream_Seek(entry->stream, li, STREAM_SEEK_SET, NULL);
1085 hres = IPersistHistory_LoadHistory(persist_history, entry->stream, NULL);
1086 IPersistHistory_Release(persist_history);
1087 return hres;
1090 HRESULT go_back(DocHost *This)
1092 if(!This->travellog.position) {
1093 WARN("No history available\n");
1094 return E_FAIL;
1097 return navigate_history(This, This->travellog.position-1);
1100 HRESULT go_forward(DocHost *This)
1102 if(This->travellog.position >= This->travellog.length) {
1103 WARN("No history available\n");
1104 return E_FAIL;
1107 return navigate_history(This, This->travellog.position+1);
1110 HRESULT get_location_url(DocHost *This, BSTR *ret)
1112 FIXME("semi-stub\n");
1114 *ret = This->url ? SysAllocString(This->url) : SysAllocStringLen(NULL, 0);
1115 if(!*ret)
1116 return E_OUTOFMEMORY;
1118 return This->url ? S_OK : S_FALSE;
1121 static inline HlinkFrame *impl_from_IHlinkFrame(IHlinkFrame *iface)
1123 return CONTAINING_RECORD(iface, HlinkFrame, IHlinkFrame_iface);
1126 static HRESULT WINAPI HlinkFrame_QueryInterface(IHlinkFrame *iface, REFIID riid, void **ppv)
1128 HlinkFrame *This = impl_from_IHlinkFrame(iface);
1129 return IUnknown_QueryInterface(This->outer, riid, ppv);
1132 static ULONG WINAPI HlinkFrame_AddRef(IHlinkFrame *iface)
1134 HlinkFrame *This = impl_from_IHlinkFrame(iface);
1135 return IUnknown_AddRef(This->outer);
1138 static ULONG WINAPI HlinkFrame_Release(IHlinkFrame *iface)
1140 HlinkFrame *This = impl_from_IHlinkFrame(iface);
1141 return IUnknown_Release(This->outer);
1144 static HRESULT WINAPI HlinkFrame_SetBrowseContext(IHlinkFrame *iface,
1145 IHlinkBrowseContext *pihlbc)
1147 HlinkFrame *This = impl_from_IHlinkFrame(iface);
1148 FIXME("(%p)->(%p)\n", This, pihlbc);
1149 return E_NOTIMPL;
1152 static HRESULT WINAPI HlinkFrame_GetBrowseContext(IHlinkFrame *iface,
1153 IHlinkBrowseContext **ppihlbc)
1155 HlinkFrame *This = impl_from_IHlinkFrame(iface);
1156 FIXME("(%p)->(%p)\n", This, ppihlbc);
1157 return E_NOTIMPL;
1160 static HRESULT WINAPI HlinkFrame_Navigate(IHlinkFrame *iface, DWORD grfHLNF, LPBC pbc,
1161 IBindStatusCallback *pibsc, IHlink *pihlNavigate)
1163 HlinkFrame *This = impl_from_IHlinkFrame(iface);
1164 IMoniker *mon;
1165 LPWSTR location = NULL;
1167 TRACE("(%p)->(%08x %p %p %p)\n", This, grfHLNF, pbc, pibsc, pihlNavigate);
1169 if(grfHLNF)
1170 FIXME("unsupported grfHLNF=%08x\n", grfHLNF);
1172 /* Windows calls GetTargetFrameName here. */
1174 IHlink_GetMonikerReference(pihlNavigate, 1, &mon, &location);
1176 if(location) {
1177 FIXME("location = %s\n", debugstr_w(location));
1178 CoTaskMemFree(location);
1181 /* Windows calls GetHlinkSite here */
1183 if(grfHLNF & HLNF_OPENINNEWWINDOW) {
1184 FIXME("Not supported HLNF_OPENINNEWWINDOW\n");
1185 return E_NOTIMPL;
1188 return navigate_hlink(This->doc_host, mon, pbc, pibsc);
1191 static HRESULT WINAPI HlinkFrame_OnNavigate(IHlinkFrame *iface, DWORD grfHLNF,
1192 IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName, DWORD dwreserved)
1194 HlinkFrame *This = impl_from_IHlinkFrame(iface);
1195 FIXME("(%p)->(%08x %p %s %s %d)\n", This, grfHLNF, pimkTarget, debugstr_w(pwzLocation),
1196 debugstr_w(pwzFriendlyName), dwreserved);
1197 return E_NOTIMPL;
1200 static HRESULT WINAPI HlinkFrame_UpdateHlink(IHlinkFrame *iface, ULONG uHLID,
1201 IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName)
1203 HlinkFrame *This = impl_from_IHlinkFrame(iface);
1204 FIXME("(%p)->(%u %p %s %s)\n", This, uHLID, pimkTarget, debugstr_w(pwzLocation),
1205 debugstr_w(pwzFriendlyName));
1206 return E_NOTIMPL;
1209 static const IHlinkFrameVtbl HlinkFrameVtbl = {
1210 HlinkFrame_QueryInterface,
1211 HlinkFrame_AddRef,
1212 HlinkFrame_Release,
1213 HlinkFrame_SetBrowseContext,
1214 HlinkFrame_GetBrowseContext,
1215 HlinkFrame_Navigate,
1216 HlinkFrame_OnNavigate,
1217 HlinkFrame_UpdateHlink
1220 static inline HlinkFrame *impl_from_ITargetFrame2(ITargetFrame2 *iface)
1222 return CONTAINING_RECORD(iface, HlinkFrame, IHlinkFrame_iface);
1225 static HRESULT WINAPI TargetFrame2_QueryInterface(ITargetFrame2 *iface, REFIID riid, void **ppv)
1227 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1228 return IUnknown_QueryInterface(This->outer, riid, ppv);
1231 static ULONG WINAPI TargetFrame2_AddRef(ITargetFrame2 *iface)
1233 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1234 return IUnknown_AddRef(This->outer);
1237 static ULONG WINAPI TargetFrame2_Release(ITargetFrame2 *iface)
1239 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1240 return IUnknown_Release(This->outer);
1243 static HRESULT WINAPI TargetFrame2_SetFrameName(ITargetFrame2 *iface, LPCWSTR pszFrameName)
1245 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1246 FIXME("(%p)->(%s)\n", This, debugstr_w(pszFrameName));
1247 return E_NOTIMPL;
1250 static HRESULT WINAPI TargetFrame2_GetFrameName(ITargetFrame2 *iface, LPWSTR *ppszFrameName)
1252 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1253 FIXME("(%p)->(%p)\n", This, ppszFrameName);
1254 return E_NOTIMPL;
1257 static HRESULT WINAPI TargetFrame2_GetParentFrame(ITargetFrame2 *iface, IUnknown **ppunkParent)
1259 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1260 FIXME("(%p)->(%p)\n", This, ppunkParent);
1261 return E_NOTIMPL;
1264 static HRESULT WINAPI TargetFrame2_SetFrameSrc(ITargetFrame2 *iface, LPCWSTR pszFrameSrc)
1266 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1267 FIXME("(%p)->(%s)\n", This, debugstr_w(pszFrameSrc));
1268 return E_NOTIMPL;
1271 static HRESULT WINAPI TargetFrame2_GetFrameSrc(ITargetFrame2 *iface, LPWSTR *ppszFrameSrc)
1273 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1274 FIXME("(%p)->()\n", This);
1275 return E_NOTIMPL;
1278 static HRESULT WINAPI TargetFrame2_GetFramesContainer(ITargetFrame2 *iface, IOleContainer **ppContainer)
1280 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1281 FIXME("(%p)->(%p)\n", This, ppContainer);
1282 return E_NOTIMPL;
1285 static HRESULT WINAPI TargetFrame2_SetFrameOptions(ITargetFrame2 *iface, DWORD dwFlags)
1287 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1288 FIXME("(%p)->(%x)\n", This, dwFlags);
1289 return E_NOTIMPL;
1292 static HRESULT WINAPI TargetFrame2_GetFrameOptions(ITargetFrame2 *iface, DWORD *pdwFlags)
1294 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1295 FIXME("(%p)->(%p)\n", This, pdwFlags);
1296 return E_NOTIMPL;
1299 static HRESULT WINAPI TargetFrame2_SetFrameMargins(ITargetFrame2 *iface, DWORD dwWidth, DWORD dwHeight)
1301 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1302 FIXME("(%p)->(%d %d)\n", This, dwWidth, dwHeight);
1303 return E_NOTIMPL;
1306 static HRESULT WINAPI TargetFrame2_GetFrameMargins(ITargetFrame2 *iface, DWORD *pdwWidth, DWORD *pdwHeight)
1308 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1309 FIXME("(%p)->(%p %p)\n", This, pdwWidth, pdwHeight);
1310 return E_NOTIMPL;
1313 static HRESULT WINAPI TargetFrame2_FindFrame(ITargetFrame2 *iface, LPCWSTR pszTargetName, DWORD dwFlags, IUnknown **ppunkTargetFrame)
1315 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1316 FIXME("(%p)->(%s %x %p)\n", This, debugstr_w(pszTargetName), dwFlags, ppunkTargetFrame);
1317 return E_NOTIMPL;
1320 static HRESULT WINAPI TargetFrame2_GetTargetAlias(ITargetFrame2 *iface, LPCWSTR pszTargetName, LPWSTR *ppszTargetAlias)
1322 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1323 FIXME("(%p)->(%s %p)\n", This, debugstr_w(pszTargetName), ppszTargetAlias);
1324 return E_NOTIMPL;
1327 static const ITargetFrame2Vtbl TargetFrame2Vtbl = {
1328 TargetFrame2_QueryInterface,
1329 TargetFrame2_AddRef,
1330 TargetFrame2_Release,
1331 TargetFrame2_SetFrameName,
1332 TargetFrame2_GetFrameName,
1333 TargetFrame2_GetParentFrame,
1334 TargetFrame2_SetFrameSrc,
1335 TargetFrame2_GetFrameSrc,
1336 TargetFrame2_GetFramesContainer,
1337 TargetFrame2_SetFrameOptions,
1338 TargetFrame2_GetFrameOptions,
1339 TargetFrame2_SetFrameMargins,
1340 TargetFrame2_GetFrameMargins,
1341 TargetFrame2_FindFrame,
1342 TargetFrame2_GetTargetAlias
1345 static inline HlinkFrame *impl_from_ITargetFramePriv2(ITargetFramePriv2 *iface)
1347 return CONTAINING_RECORD(iface, HlinkFrame, ITargetFramePriv2_iface);
1350 static HRESULT WINAPI TargetFramePriv2_QueryInterface(ITargetFramePriv2 *iface, REFIID riid, void **ppv)
1352 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1353 return IUnknown_QueryInterface(This->outer, riid, ppv);
1356 static ULONG WINAPI TargetFramePriv2_AddRef(ITargetFramePriv2 *iface)
1358 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1359 return IUnknown_AddRef(This->outer);
1362 static ULONG WINAPI TargetFramePriv2_Release(ITargetFramePriv2 *iface)
1364 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1365 return IUnknown_Release(This->outer);
1368 static HRESULT WINAPI TargetFramePriv2_FindFrameDownwards(ITargetFramePriv2 *iface,
1369 LPCWSTR pszTargetName, DWORD dwFlags, IUnknown **ppunkTargetFrame)
1371 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1372 FIXME("(%p)->(%s %x %p)\n", This, debugstr_w(pszTargetName), dwFlags, ppunkTargetFrame);
1373 return E_NOTIMPL;
1376 static HRESULT WINAPI TargetFramePriv2_FindFrameInContext(ITargetFramePriv2 *iface,
1377 LPCWSTR pszTargetName, IUnknown *punkContextFrame, DWORD dwFlags, IUnknown **ppunkTargetFrame)
1379 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1380 FIXME("(%p)->(%s %p %x %p)\n", This, debugstr_w(pszTargetName), punkContextFrame, dwFlags, ppunkTargetFrame);
1381 return E_NOTIMPL;
1384 static HRESULT WINAPI TargetFramePriv2_OnChildFrameActivate(ITargetFramePriv2 *iface, IUnknown *pUnkChildFrame)
1386 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1387 FIXME("(%p)->(%p)\n", This, pUnkChildFrame);
1388 return E_NOTIMPL;
1391 static HRESULT WINAPI TargetFramePriv2_OnChildFrameDeactivate(ITargetFramePriv2 *iface, IUnknown *pUnkChildFrame)
1393 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1394 FIXME("(%p)->(%p)\n", This, pUnkChildFrame);
1395 return E_NOTIMPL;
1398 static HRESULT WINAPI TargetFramePriv2_NavigateHack(ITargetFramePriv2 *iface, DWORD grfHLNF, LPBC pbc,
1399 IBindStatusCallback *pibsc, LPCWSTR pszTargetName, LPCWSTR pszUrl, LPCWSTR pszLocation)
1401 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1402 FIXME("(%p)->(%x %p %p %s %s %s)\n", This, grfHLNF, pbc, pibsc, debugstr_w(pszTargetName),
1403 debugstr_w(pszUrl), debugstr_w(pszLocation));
1404 return E_NOTIMPL;
1407 static HRESULT WINAPI TargetFramePriv2_FindBrowserByIndex(ITargetFramePriv2 *iface, DWORD dwID, IUnknown **ppunkBrowser)
1409 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1410 FIXME("(%p)->(%d %p)\n", This, dwID, ppunkBrowser);
1411 return E_NOTIMPL;
1414 static HRESULT WINAPI TargetFramePriv2_AggregatedNavigation2(ITargetFramePriv2 *iface, DWORD grfHLNF, LPBC pbc,
1415 IBindStatusCallback *pibsc, LPCWSTR pszTargetName, IUri *pUri, LPCWSTR pszLocation)
1417 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1418 IMoniker *mon;
1419 HRESULT hres;
1421 TRACE("(%p)->(%x %p %p %s %p %s)\n", This, grfHLNF, pbc, pibsc, debugstr_w(pszTargetName),
1422 pUri, debugstr_w(pszLocation));
1425 * NOTE: This is an undocumented function. It seems to be working the way it's implemented,
1426 * but I couldn't get its tests working. It's used by mshtml to load content in a new
1427 * instance of browser.
1430 hres = CreateURLMonikerEx2(NULL, pUri, &mon, 0);
1431 if(FAILED(hres))
1432 return hres;
1434 hres = navigate_hlink(This->doc_host, mon, pbc, pibsc);
1435 IMoniker_Release(mon);
1436 return hres;
1439 static const ITargetFramePriv2Vtbl TargetFramePriv2Vtbl = {
1440 TargetFramePriv2_QueryInterface,
1441 TargetFramePriv2_AddRef,
1442 TargetFramePriv2_Release,
1443 TargetFramePriv2_FindFrameDownwards,
1444 TargetFramePriv2_FindFrameInContext,
1445 TargetFramePriv2_OnChildFrameActivate,
1446 TargetFramePriv2_OnChildFrameDeactivate,
1447 TargetFramePriv2_NavigateHack,
1448 TargetFramePriv2_FindBrowserByIndex,
1449 TargetFramePriv2_AggregatedNavigation2
1452 static inline HlinkFrame *impl_from_IWebBrowserPriv2IE9(IWebBrowserPriv2IE9 *iface)
1454 return CONTAINING_RECORD(iface, HlinkFrame, IWebBrowserPriv2IE9_iface);
1457 static HRESULT WINAPI WebBrowserPriv2IE9_QueryInterface(IWebBrowserPriv2IE9 *iface, REFIID riid, void **ppv)
1459 HlinkFrame *This = impl_from_IWebBrowserPriv2IE9(iface);
1460 return IUnknown_QueryInterface(This->outer, riid, ppv);
1463 static ULONG WINAPI WebBrowserPriv2IE9_AddRef(IWebBrowserPriv2IE9 *iface)
1465 HlinkFrame *This = impl_from_IWebBrowserPriv2IE9(iface);
1466 return IUnknown_AddRef(This->outer);
1469 static ULONG WINAPI WebBrowserPriv2IE9_Release(IWebBrowserPriv2IE9 *iface)
1471 HlinkFrame *This = impl_from_IWebBrowserPriv2IE9(iface);
1472 return IUnknown_Release(This->outer);
1475 static HRESULT WINAPI WebBrowserPriv2IE9_NavigateWithBindCtx2(IWebBrowserPriv2IE9 *iface, IUri *uri, VARIANT *flags,
1476 VARIANT *target_frame, VARIANT *post_data, VARIANT *headers, IBindCtx *bind_ctx, LPOLESTR url_fragment, DWORD unused)
1478 HlinkFrame *This = impl_from_IWebBrowserPriv2IE9(iface);
1479 FIXME("(%p)->(%p %s %s %s %s %p %s)\n", This, uri, debugstr_variant(flags), debugstr_variant(target_frame),
1480 debugstr_variant(post_data), debugstr_variant(headers), bind_ctx, debugstr_w(url_fragment));
1481 return E_NOTIMPL;
1484 static const IWebBrowserPriv2IE9Vtbl WebBrowserPriv2IE9Vtbl = {
1485 WebBrowserPriv2IE9_QueryInterface,
1486 WebBrowserPriv2IE9_AddRef,
1487 WebBrowserPriv2IE9_Release,
1488 WebBrowserPriv2IE9_NavigateWithBindCtx2
1491 BOOL HlinkFrame_QI(HlinkFrame *This, REFIID riid, void **ppv)
1493 if(IsEqualGUID(&IID_IHlinkFrame, riid)) {
1494 TRACE("(%p)->(IID_IHlinkFrame %p)\n", This, ppv);
1495 *ppv = &This->IHlinkFrame_iface;
1496 }else if(IsEqualGUID(&IID_ITargetFrame2, riid)) {
1497 TRACE("(%p)->(IID_ITargetFrame2 %p)\n", This, ppv);
1498 *ppv = &This->ITargetFrame2_iface;
1499 }else if(IsEqualGUID(&IID_ITargetFramePriv, riid)) {
1500 TRACE("(%p)->(IID_ITargetFramePriv %p)\n", This, ppv);
1501 *ppv = &This->ITargetFramePriv2_iface;
1502 }else if(IsEqualGUID(&IID_ITargetFramePriv2, riid)) {
1503 TRACE("(%p)->(IID_ITargetFramePriv2 %p)\n", This, ppv);
1504 *ppv = &This->ITargetFramePriv2_iface;
1505 }else if(IsEqualGUID(&IID_IWebBrowserPriv2IE9, riid)) {
1506 TRACE("(%p)->(IID_IWebBrowserPriv2IE9 %p)\n", This, ppv);
1507 *ppv = &This->IWebBrowserPriv2IE9_iface;
1508 }else {
1509 return FALSE;
1512 IUnknown_AddRef((IUnknown*)*ppv);
1513 return TRUE;
1516 void HlinkFrame_Init(HlinkFrame *This, IUnknown *outer, DocHost *doc_host)
1518 This->IHlinkFrame_iface.lpVtbl = &HlinkFrameVtbl;
1519 This->ITargetFrame2_iface.lpVtbl = &TargetFrame2Vtbl;
1520 This->ITargetFramePriv2_iface.lpVtbl = &TargetFramePriv2Vtbl;
1521 This->IWebBrowserPriv2IE9_iface.lpVtbl = &WebBrowserPriv2IE9Vtbl;
1523 This->outer = outer;
1524 This->doc_host = doc_host;