Release 1.6-rc2.
[wine/testsucceed.git] / dlls / ieframe / navigate.c
blobd730b10f4fb8a4423a54748e12644ee4cba1c68d
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)
932 || (TargetFrameName && V_VT(TargetFrameName) != VT_EMPTY))
933 FIXME("Unsupported args (Flags %p:%d; TargetFrameName %p:%d)\n",
934 Flags, Flags ? V_VT(Flags) : -1, TargetFrameName,
935 TargetFrameName ? V_VT(TargetFrameName) : -1);
937 if(PostData && V_VT(PostData) == (VT_ARRAY | VT_UI1) && V_ARRAY(PostData)) {
938 SafeArrayAccessData(V_ARRAY(PostData), (void**)&post_data);
939 post_data_len = V_ARRAY(PostData)->rgsabound[0].cElements;
942 if(Headers && V_VT(Headers) == VT_BSTR) {
943 headers = V_BSTR(Headers);
944 TRACE("Headers: %s\n", debugstr_w(headers));
947 set_doc_state(This, READYSTATE_LOADING);
948 This->ready_state = READYSTATE_LOADING;
950 if(This->doc_navigate) {
951 WCHAR new_url[INTERNET_MAX_URL_LENGTH];
953 if(PathIsURLW(url)) {
954 new_url[0] = 0;
955 }else {
956 DWORD size;
958 size = sizeof(new_url)/sizeof(WCHAR);
959 hres = UrlApplySchemeW(url, new_url, &size,
960 URL_APPLY_GUESSSCHEME | URL_APPLY_GUESSFILE | URL_APPLY_DEFAULT);
961 if(FAILED(hres)) {
962 WARN("UrlApplyScheme failed: %08x\n", hres);
963 new_url[0] = 0;
967 hres = async_doc_navigate(This, *new_url ? new_url : url, headers, post_data,
968 post_data_len, TRUE);
969 }else {
970 task_navigate_bsc_t *task;
972 task = heap_alloc(sizeof(*task));
973 task->bsc = create_callback(This, url, post_data, post_data_len, headers);
974 push_dochost_task(This, &task->header, navigate_bsc_proc, navigate_bsc_task_destr, This->url == NULL);
977 if(post_data)
978 SafeArrayUnaccessData(V_ARRAY(PostData));
980 return hres;
983 static HRESULT navigate_hlink(DocHost *This, IMoniker *mon, IBindCtx *bindctx,
984 IBindStatusCallback *callback)
986 IHttpNegotiate *http_negotiate;
987 BindStatusCallback *bsc;
988 PBYTE post_data = NULL;
989 ULONG post_data_len = 0;
990 LPWSTR headers = NULL, url;
991 BINDINFO bindinfo;
992 DWORD bindf = 0;
993 HRESULT hres;
995 TRACE("\n");
997 hres = IMoniker_GetDisplayName(mon, 0, NULL, &url);
998 if(FAILED(hres))
999 FIXME("GetDisplayName failed: %08x\n", hres);
1001 hres = IBindStatusCallback_QueryInterface(callback, &IID_IHttpNegotiate,
1002 (void**)&http_negotiate);
1003 if(SUCCEEDED(hres)) {
1004 static const WCHAR null_string[] = {0};
1006 IHttpNegotiate_BeginningTransaction(http_negotiate, null_string, null_string, 0,
1007 &headers);
1008 IHttpNegotiate_Release(http_negotiate);
1011 memset(&bindinfo, 0, sizeof(bindinfo));
1012 bindinfo.cbSize = sizeof(bindinfo);
1014 hres = IBindStatusCallback_GetBindInfo(callback, &bindf, &bindinfo);
1015 dump_BINDINFO(&bindinfo);
1016 if(bindinfo.dwBindVerb == BINDVERB_POST) {
1017 post_data_len = bindinfo.cbstgmedData;
1018 if(post_data_len)
1019 post_data = bindinfo.stgmedData.u.hGlobal;
1022 if(This->doc_navigate) {
1023 hres = async_doc_navigate(This, url, headers, post_data, post_data_len, FALSE);
1024 }else {
1025 bsc = create_callback(This, url, post_data, post_data_len, headers);
1026 hres = navigate_bsc(This, bsc, mon);
1027 IBindStatusCallback_Release(&bsc->IBindStatusCallback_iface);
1030 CoTaskMemFree(url);
1031 CoTaskMemFree(headers);
1032 ReleaseBindInfo(&bindinfo);
1034 return hres;
1037 HRESULT go_home(DocHost *This)
1039 HKEY hkey;
1040 DWORD res, type, size;
1041 WCHAR wszPageName[MAX_PATH];
1042 static const WCHAR wszAboutBlank[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
1043 static const WCHAR wszStartPage[] = {'S','t','a','r','t',' ','P','a','g','e',0};
1044 static const WCHAR wszSubKey[] = {'S','o','f','t','w','a','r','e','\\',
1045 'M','i','c','r','o','s','o','f','t','\\',
1046 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
1047 'M','a','i','n',0};
1049 res = RegOpenKeyW(HKEY_CURRENT_USER, wszSubKey, &hkey);
1050 if (res != ERROR_SUCCESS)
1051 return navigate_url(This, wszAboutBlank, NULL, NULL, NULL, NULL);
1053 size = sizeof(wszPageName);
1054 res = RegQueryValueExW(hkey, wszStartPage, NULL, &type, (LPBYTE)wszPageName, &size);
1055 RegCloseKey(hkey);
1056 if (res != ERROR_SUCCESS || type != REG_SZ)
1057 return navigate_url(This, wszAboutBlank, NULL, NULL, NULL, NULL);
1059 return navigate_url(This, wszPageName, NULL, NULL, NULL, NULL);
1062 static HRESULT navigate_history(DocHost *This, unsigned travellog_pos)
1064 IPersistHistory *persist_history;
1065 travellog_entry_t *entry;
1066 LARGE_INTEGER li;
1067 HRESULT hres;
1069 if(!This->doc_navigate) {
1070 FIXME("unsupported doc_navigate FALSE\n");
1071 return E_NOTIMPL;
1074 This->travellog.loading_pos = travellog_pos;
1075 entry = This->travellog.log + This->travellog.loading_pos;
1077 if(!entry->stream)
1078 return async_doc_navigate(This, entry->url, NULL, NULL, 0, FALSE);
1080 hres = IUnknown_QueryInterface(This->document, &IID_IPersistHistory, (void**)&persist_history);
1081 if(FAILED(hres))
1082 return hres;
1084 li.QuadPart = 0;
1085 IStream_Seek(entry->stream, li, STREAM_SEEK_SET, NULL);
1087 hres = IPersistHistory_LoadHistory(persist_history, entry->stream, NULL);
1088 IPersistHistory_Release(persist_history);
1089 return hres;
1092 HRESULT go_back(DocHost *This)
1094 if(!This->travellog.position) {
1095 WARN("No history available\n");
1096 return E_FAIL;
1099 return navigate_history(This, This->travellog.position-1);
1102 HRESULT go_forward(DocHost *This)
1104 if(This->travellog.position >= This->travellog.length) {
1105 WARN("No history available\n");
1106 return E_FAIL;
1109 return navigate_history(This, This->travellog.position+1);
1112 HRESULT get_location_url(DocHost *This, BSTR *ret)
1114 FIXME("semi-stub\n");
1116 *ret = This->url ? SysAllocString(This->url) : SysAllocStringLen(NULL, 0);
1117 if(!*ret)
1118 return E_OUTOFMEMORY;
1120 return This->url ? S_OK : S_FALSE;
1123 static inline HlinkFrame *impl_from_IHlinkFrame(IHlinkFrame *iface)
1125 return CONTAINING_RECORD(iface, HlinkFrame, IHlinkFrame_iface);
1128 static HRESULT WINAPI HlinkFrame_QueryInterface(IHlinkFrame *iface, REFIID riid, void **ppv)
1130 HlinkFrame *This = impl_from_IHlinkFrame(iface);
1131 return IUnknown_QueryInterface(This->outer, riid, ppv);
1134 static ULONG WINAPI HlinkFrame_AddRef(IHlinkFrame *iface)
1136 HlinkFrame *This = impl_from_IHlinkFrame(iface);
1137 return IUnknown_AddRef(This->outer);
1140 static ULONG WINAPI HlinkFrame_Release(IHlinkFrame *iface)
1142 HlinkFrame *This = impl_from_IHlinkFrame(iface);
1143 return IUnknown_Release(This->outer);
1146 static HRESULT WINAPI HlinkFrame_SetBrowseContext(IHlinkFrame *iface,
1147 IHlinkBrowseContext *pihlbc)
1149 HlinkFrame *This = impl_from_IHlinkFrame(iface);
1150 FIXME("(%p)->(%p)\n", This, pihlbc);
1151 return E_NOTIMPL;
1154 static HRESULT WINAPI HlinkFrame_GetBrowseContext(IHlinkFrame *iface,
1155 IHlinkBrowseContext **ppihlbc)
1157 HlinkFrame *This = impl_from_IHlinkFrame(iface);
1158 FIXME("(%p)->(%p)\n", This, ppihlbc);
1159 return E_NOTIMPL;
1162 static HRESULT WINAPI HlinkFrame_Navigate(IHlinkFrame *iface, DWORD grfHLNF, LPBC pbc,
1163 IBindStatusCallback *pibsc, IHlink *pihlNavigate)
1165 HlinkFrame *This = impl_from_IHlinkFrame(iface);
1166 IMoniker *mon;
1167 LPWSTR location = NULL;
1169 TRACE("(%p)->(%08x %p %p %p)\n", This, grfHLNF, pbc, pibsc, pihlNavigate);
1171 if(grfHLNF)
1172 FIXME("unsupported grfHLNF=%08x\n", grfHLNF);
1174 /* Windows calls GetTargetFrameName here. */
1176 IHlink_GetMonikerReference(pihlNavigate, 1, &mon, &location);
1178 if(location) {
1179 FIXME("location = %s\n", debugstr_w(location));
1180 CoTaskMemFree(location);
1183 /* Windows calls GetHlinkSite here */
1185 if(grfHLNF & HLNF_OPENINNEWWINDOW) {
1186 FIXME("Not supported HLNF_OPENINNEWWINDOW\n");
1187 return E_NOTIMPL;
1190 return navigate_hlink(This->doc_host, mon, pbc, pibsc);
1193 static HRESULT WINAPI HlinkFrame_OnNavigate(IHlinkFrame *iface, DWORD grfHLNF,
1194 IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName, DWORD dwreserved)
1196 HlinkFrame *This = impl_from_IHlinkFrame(iface);
1197 FIXME("(%p)->(%08x %p %s %s %d)\n", This, grfHLNF, pimkTarget, debugstr_w(pwzLocation),
1198 debugstr_w(pwzFriendlyName), dwreserved);
1199 return E_NOTIMPL;
1202 static HRESULT WINAPI HlinkFrame_UpdateHlink(IHlinkFrame *iface, ULONG uHLID,
1203 IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName)
1205 HlinkFrame *This = impl_from_IHlinkFrame(iface);
1206 FIXME("(%p)->(%u %p %s %s)\n", This, uHLID, pimkTarget, debugstr_w(pwzLocation),
1207 debugstr_w(pwzFriendlyName));
1208 return E_NOTIMPL;
1211 static const IHlinkFrameVtbl HlinkFrameVtbl = {
1212 HlinkFrame_QueryInterface,
1213 HlinkFrame_AddRef,
1214 HlinkFrame_Release,
1215 HlinkFrame_SetBrowseContext,
1216 HlinkFrame_GetBrowseContext,
1217 HlinkFrame_Navigate,
1218 HlinkFrame_OnNavigate,
1219 HlinkFrame_UpdateHlink
1222 static inline HlinkFrame *impl_from_ITargetFrame2(ITargetFrame2 *iface)
1224 return CONTAINING_RECORD(iface, HlinkFrame, IHlinkFrame_iface);
1227 static HRESULT WINAPI TargetFrame2_QueryInterface(ITargetFrame2 *iface, REFIID riid, void **ppv)
1229 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1230 return IUnknown_QueryInterface(This->outer, riid, ppv);
1233 static ULONG WINAPI TargetFrame2_AddRef(ITargetFrame2 *iface)
1235 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1236 return IUnknown_AddRef(This->outer);
1239 static ULONG WINAPI TargetFrame2_Release(ITargetFrame2 *iface)
1241 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1242 return IUnknown_Release(This->outer);
1245 static HRESULT WINAPI TargetFrame2_SetFrameName(ITargetFrame2 *iface, LPCWSTR pszFrameName)
1247 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1248 FIXME("(%p)->(%s)\n", This, debugstr_w(pszFrameName));
1249 return E_NOTIMPL;
1252 static HRESULT WINAPI TargetFrame2_GetFrameName(ITargetFrame2 *iface, LPWSTR *ppszFrameName)
1254 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1255 FIXME("(%p)->(%p)\n", This, ppszFrameName);
1256 return E_NOTIMPL;
1259 static HRESULT WINAPI TargetFrame2_GetParentFrame(ITargetFrame2 *iface, IUnknown **ppunkParent)
1261 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1262 FIXME("(%p)->(%p)\n", This, ppunkParent);
1263 return E_NOTIMPL;
1266 static HRESULT WINAPI TargetFrame2_SetFrameSrc(ITargetFrame2 *iface, LPCWSTR pszFrameSrc)
1268 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1269 FIXME("(%p)->(%s)\n", This, debugstr_w(pszFrameSrc));
1270 return E_NOTIMPL;
1273 static HRESULT WINAPI TargetFrame2_GetFrameSrc(ITargetFrame2 *iface, LPWSTR *ppszFrameSrc)
1275 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1276 FIXME("(%p)->()\n", This);
1277 return E_NOTIMPL;
1280 static HRESULT WINAPI TargetFrame2_GetFramesContainer(ITargetFrame2 *iface, IOleContainer **ppContainer)
1282 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1283 FIXME("(%p)->(%p)\n", This, ppContainer);
1284 return E_NOTIMPL;
1287 static HRESULT WINAPI TargetFrame2_SetFrameOptions(ITargetFrame2 *iface, DWORD dwFlags)
1289 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1290 FIXME("(%p)->(%x)\n", This, dwFlags);
1291 return E_NOTIMPL;
1294 static HRESULT WINAPI TargetFrame2_GetFrameOptions(ITargetFrame2 *iface, DWORD *pdwFlags)
1296 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1297 FIXME("(%p)->(%p)\n", This, pdwFlags);
1298 return E_NOTIMPL;
1301 static HRESULT WINAPI TargetFrame2_SetFrameMargins(ITargetFrame2 *iface, DWORD dwWidth, DWORD dwHeight)
1303 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1304 FIXME("(%p)->(%d %d)\n", This, dwWidth, dwHeight);
1305 return E_NOTIMPL;
1308 static HRESULT WINAPI TargetFrame2_GetFrameMargins(ITargetFrame2 *iface, DWORD *pdwWidth, DWORD *pdwHeight)
1310 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1311 FIXME("(%p)->(%p %p)\n", This, pdwWidth, pdwHeight);
1312 return E_NOTIMPL;
1315 static HRESULT WINAPI TargetFrame2_FindFrame(ITargetFrame2 *iface, LPCWSTR pszTargetName, DWORD dwFlags, IUnknown **ppunkTargetFrame)
1317 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1318 FIXME("(%p)->(%s %x %p)\n", This, debugstr_w(pszTargetName), dwFlags, ppunkTargetFrame);
1319 return E_NOTIMPL;
1322 static HRESULT WINAPI TargetFrame2_GetTargetAlias(ITargetFrame2 *iface, LPCWSTR pszTargetName, LPWSTR *ppszTargetAlias)
1324 HlinkFrame *This = impl_from_ITargetFrame2(iface);
1325 FIXME("(%p)->(%s %p)\n", This, debugstr_w(pszTargetName), ppszTargetAlias);
1326 return E_NOTIMPL;
1329 static const ITargetFrame2Vtbl TargetFrame2Vtbl = {
1330 TargetFrame2_QueryInterface,
1331 TargetFrame2_AddRef,
1332 TargetFrame2_Release,
1333 TargetFrame2_SetFrameName,
1334 TargetFrame2_GetFrameName,
1335 TargetFrame2_GetParentFrame,
1336 TargetFrame2_SetFrameSrc,
1337 TargetFrame2_GetFrameSrc,
1338 TargetFrame2_GetFramesContainer,
1339 TargetFrame2_SetFrameOptions,
1340 TargetFrame2_GetFrameOptions,
1341 TargetFrame2_SetFrameMargins,
1342 TargetFrame2_GetFrameMargins,
1343 TargetFrame2_FindFrame,
1344 TargetFrame2_GetTargetAlias
1347 static inline HlinkFrame *impl_from_ITargetFramePriv2(ITargetFramePriv2 *iface)
1349 return CONTAINING_RECORD(iface, HlinkFrame, ITargetFramePriv2_iface);
1352 static HRESULT WINAPI TargetFramePriv2_QueryInterface(ITargetFramePriv2 *iface, REFIID riid, void **ppv)
1354 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1355 return IUnknown_QueryInterface(This->outer, riid, ppv);
1358 static ULONG WINAPI TargetFramePriv2_AddRef(ITargetFramePriv2 *iface)
1360 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1361 return IUnknown_AddRef(This->outer);
1364 static ULONG WINAPI TargetFramePriv2_Release(ITargetFramePriv2 *iface)
1366 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1367 return IUnknown_Release(This->outer);
1370 static HRESULT WINAPI TargetFramePriv2_FindFrameDownwards(ITargetFramePriv2 *iface,
1371 LPCWSTR pszTargetName, DWORD dwFlags, IUnknown **ppunkTargetFrame)
1373 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1374 FIXME("(%p)->(%s %x %p)\n", This, debugstr_w(pszTargetName), dwFlags, ppunkTargetFrame);
1375 return E_NOTIMPL;
1378 static HRESULT WINAPI TargetFramePriv2_FindFrameInContext(ITargetFramePriv2 *iface,
1379 LPCWSTR pszTargetName, IUnknown *punkContextFrame, DWORD dwFlags, IUnknown **ppunkTargetFrame)
1381 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1382 FIXME("(%p)->(%s %p %x %p)\n", This, debugstr_w(pszTargetName), punkContextFrame, dwFlags, ppunkTargetFrame);
1383 return E_NOTIMPL;
1386 static HRESULT WINAPI TargetFramePriv2_OnChildFrameActivate(ITargetFramePriv2 *iface, IUnknown *pUnkChildFrame)
1388 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1389 FIXME("(%p)->(%p)\n", This, pUnkChildFrame);
1390 return E_NOTIMPL;
1393 static HRESULT WINAPI TargetFramePriv2_OnChildFrameDeactivate(ITargetFramePriv2 *iface, IUnknown *pUnkChildFrame)
1395 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1396 FIXME("(%p)->(%p)\n", This, pUnkChildFrame);
1397 return E_NOTIMPL;
1400 static HRESULT WINAPI TargetFramePriv2_NavigateHack(ITargetFramePriv2 *iface, DWORD grfHLNF, LPBC pbc,
1401 IBindStatusCallback *pibsc, LPCWSTR pszTargetName, LPCWSTR pszUrl, LPCWSTR pszLocation)
1403 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1404 FIXME("(%p)->(%x %p %p %s %s %s)\n", This, grfHLNF, pbc, pibsc, debugstr_w(pszTargetName),
1405 debugstr_w(pszUrl), debugstr_w(pszLocation));
1406 return E_NOTIMPL;
1409 static HRESULT WINAPI TargetFramePriv2_FindBrowserByIndex(ITargetFramePriv2 *iface, DWORD dwID, IUnknown **ppunkBrowser)
1411 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1412 FIXME("(%p)->(%d %p)\n", This, dwID, ppunkBrowser);
1413 return E_NOTIMPL;
1416 static HRESULT WINAPI TargetFramePriv2_AggregatedNavigation2(ITargetFramePriv2 *iface, DWORD grfHLNF, LPBC pbc,
1417 IBindStatusCallback *pibsc, LPCWSTR pszTargetName, IUri *pUri, LPCWSTR pszLocation)
1419 HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
1420 IMoniker *mon;
1421 HRESULT hres;
1423 TRACE("(%p)->(%x %p %p %s %p %s)\n", This, grfHLNF, pbc, pibsc, debugstr_w(pszTargetName),
1424 pUri, debugstr_w(pszLocation));
1427 * NOTE: This is an undocumented function. It seems to be working the way it's implemented,
1428 * but I couldn't get its tests working. It's used by mshtml to load content in a new
1429 * instance of browser.
1432 hres = CreateURLMonikerEx2(NULL, pUri, &mon, 0);
1433 if(FAILED(hres))
1434 return hres;
1436 hres = navigate_hlink(This->doc_host, mon, pbc, pibsc);
1437 IMoniker_Release(mon);
1438 return hres;
1441 static const ITargetFramePriv2Vtbl TargetFramePriv2Vtbl = {
1442 TargetFramePriv2_QueryInterface,
1443 TargetFramePriv2_AddRef,
1444 TargetFramePriv2_Release,
1445 TargetFramePriv2_FindFrameDownwards,
1446 TargetFramePriv2_FindFrameInContext,
1447 TargetFramePriv2_OnChildFrameActivate,
1448 TargetFramePriv2_OnChildFrameDeactivate,
1449 TargetFramePriv2_NavigateHack,
1450 TargetFramePriv2_FindBrowserByIndex,
1451 TargetFramePriv2_AggregatedNavigation2
1454 BOOL HlinkFrame_QI(HlinkFrame *This, REFIID riid, void **ppv)
1456 if(IsEqualGUID(&IID_IHlinkFrame, riid)) {
1457 TRACE("(%p)->(IID_IHlinkFrame %p)\n", This, ppv);
1458 *ppv = &This->IHlinkFrame_iface;
1459 }else if(IsEqualGUID(&IID_ITargetFrame2, riid)) {
1460 TRACE("(%p)->(IID_ITargetFrame2 %p)\n", This, ppv);
1461 *ppv = &This->ITargetFrame2_iface;
1462 }else if(IsEqualGUID(&IID_ITargetFramePriv, riid)) {
1463 TRACE("(%p)->(IID_ITargetFramePriv %p)\n", This, ppv);
1464 *ppv = &This->ITargetFramePriv2_iface;
1465 }else if(IsEqualGUID(&IID_ITargetFramePriv2, riid)) {
1466 TRACE("(%p)->(IID_ITargetFramePriv2 %p)\n", This, ppv);
1467 *ppv = &This->ITargetFramePriv2_iface;
1468 }else {
1469 return FALSE;
1472 IUnknown_AddRef((IUnknown*)*ppv);
1473 return TRUE;
1476 void HlinkFrame_Init(HlinkFrame *This, IUnknown *outer, DocHost *doc_host)
1478 This->IHlinkFrame_iface.lpVtbl = &HlinkFrameVtbl;
1479 This->ITargetFrame2_iface.lpVtbl = &TargetFrame2Vtbl;
1480 This->ITargetFramePriv2_iface.lpVtbl = &TargetFramePriv2Vtbl;
1482 This->outer = outer;
1483 This->doc_host = doc_host;