/*
 * Copyright 2006-2007 Jacek Caban for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define NONAMELESSUNION

#include "ieframe.h"

#include "exdispid.h"
#include "shellapi.h"
#include "winreg.h"
#include "shlwapi.h"
#include "wininet.h"
#include "mshtml.h"
#include "perhist.h"
#include "resource.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ieframe);

static const WCHAR emptyW[] = {0};

typedef struct {
    IBindStatusCallback  IBindStatusCallback_iface;
    IHttpNegotiate       IHttpNegotiate_iface;
    IHttpSecurity        IHttpSecurity_iface;

    LONG ref;

    DocHost *doc_host;
    IBinding *binding;

    BSTR url;
    HGLOBAL post_data;
    BSTR headers;
    ULONG post_data_len;
} BindStatusCallback;

static void dump_BINDINFO(BINDINFO *bi)
{
    static const char * const BINDINFOF_str[] = {
        "#0",
        "BINDINFOF_URLENCODESTGMEDDATA",
        "BINDINFOF_URLENCODEDEXTRAINFO"
    };

    static const char * const BINDVERB_str[] = {
        "BINDVERB_GET",
        "BINDVERB_POST",
        "BINDVERB_PUT",
        "BINDVERB_CUSTOM"
    };

    TRACE("\n"
            "BINDINFO = {\n"
            "    %d, %s,\n"
            "    {%d, %p, %p},\n"
            "    %s,\n"
            "    %s,\n"
            "    %s,\n"
            "    %d, %08x, %d, %d\n"
            "    {%d %p %x},\n"
            "    %s\n"
            "    %p, %d\n"
            "}\n",

            bi->cbSize, debugstr_w(bi->szExtraInfo),
            bi->stgmedData.tymed, bi->stgmedData.u.hGlobal, bi->stgmedData.pUnkForRelease,
            bi->grfBindInfoF > BINDINFOF_URLENCODEDEXTRAINFO
                ? "unknown" : BINDINFOF_str[bi->grfBindInfoF],
            bi->dwBindVerb > BINDVERB_CUSTOM
                ? "unknown" : BINDVERB_str[bi->dwBindVerb],
            debugstr_w(bi->szCustomVerb),
            bi->cbstgmedData, bi->dwOptions, bi->dwOptionsFlags, bi->dwCodePage,
            bi->securityAttributes.nLength,
            bi->securityAttributes.lpSecurityDescriptor,
            bi->securityAttributes.bInheritHandle,
            debugstr_guid(&bi->iid),
            bi->pUnk, bi->dwReserved
            );
}

static void set_status_text(BindStatusCallback *This, ULONG statuscode, LPCWSTR str)
{
    VARIANTARG arg;
    DISPPARAMS dispparams = {&arg, NULL, 1, 0};
    WCHAR fmt[IDS_STATUSFMT_MAXLEN];
    WCHAR buffer[IDS_STATUSFMT_MAXLEN + INTERNET_MAX_URL_LENGTH];

    if(!This->doc_host)
        return;

    TRACE("(%p, %d, %s)\n", This, statuscode, debugstr_w(str));
    buffer[0] = 0;
    if (statuscode && str && *str) {
        fmt[0] = 0;
        /* the format string must have one "%s" for the str */
        LoadStringW(ieframe_instance, IDS_STATUSFMT_FIRST + statuscode, fmt, IDS_STATUSFMT_MAXLEN);
        snprintfW(buffer, sizeof(buffer)/sizeof(WCHAR), fmt, str);
    }

    V_VT(&arg) = VT_BSTR;
    V_BSTR(&arg) = str ? SysAllocString(buffer) : SysAllocString(emptyW);
    TRACE("=> %s\n", debugstr_w(V_BSTR(&arg)));

    call_sink(This->doc_host->cps.wbe2, DISPID_STATUSTEXTCHANGE, &dispparams);

    if(This->doc_host->frame)
        IOleInPlaceFrame_SetStatusText(This->doc_host->frame, buffer);

    VariantClear(&arg);

}

HRESULT set_dochost_url(DocHost *This, const WCHAR *url)
{
    WCHAR *new_url;

    if(url) {
        new_url = heap_strdupW(url);
        if(!new_url)
            return E_OUTOFMEMORY;
    }else {
        new_url = NULL;
    }

    heap_free(This->url);
    This->url = new_url;

    This->container_vtbl->set_url(This, This->url);
    return S_OK;
}

void notify_download_state(DocHost *dochost, BOOL is_downloading)
{
    DISPPARAMS dwl_dp = {NULL};
    TRACE("(%x)\n", is_downloading);
    call_sink(dochost->cps.wbe2, is_downloading ? DISPID_DOWNLOADBEGIN : DISPID_DOWNLOADCOMPLETE, &dwl_dp);
}

static inline BindStatusCallback *impl_from_IBindStatusCallback(IBindStatusCallback *iface)
{
    return CONTAINING_RECORD(iface, BindStatusCallback, IBindStatusCallback_iface);
}

static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *iface,
                                                        REFIID riid, void **ppv)
{
    BindStatusCallback *This = impl_from_IBindStatusCallback(iface);

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
        *ppv = &This->IBindStatusCallback_iface;
    }else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) {
        TRACE("(%p)->(IID_IBindStatusCallback %p)\n", This, ppv);
        *ppv = &This->IBindStatusCallback_iface;
    }else if(IsEqualGUID(&IID_IHttpNegotiate, riid)) {
        TRACE("(%p)->(IID_IHttpNegotiate %p)\n", This, ppv);
        *ppv = &This->IHttpNegotiate_iface;
    }else if(IsEqualGUID(&IID_IWindowForBindingUI, riid)) {
        TRACE("(%p)->(IID_IWindowForBindingUI %p)\n", This, ppv);
        *ppv = &This->IHttpSecurity_iface;
    }else if(IsEqualGUID(&IID_IHttpSecurity, riid)) {
        TRACE("(%p)->(IID_IHttpSecurity %p)\n", This, ppv);
        *ppv = &This->IHttpSecurity_iface;
    }else {
        *ppv = NULL;
        WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface)
{
    BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
    LONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    return ref;
}

static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface)
{
    BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
    LONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if(!ref) {
        if(This->doc_host)
            IOleClientSite_Release(&This->doc_host->IOleClientSite_iface);
        if(This->binding)
            IBinding_Release(This->binding);
        if(This->post_data)
            GlobalFree(This->post_data);
        SysFreeString(This->headers);
        SysFreeString(This->url);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface,
       DWORD dwReserved, IBinding *pbind)
{
    BindStatusCallback *This = impl_from_IBindStatusCallback(iface);

    TRACE("(%p)->(%d %p)\n", This, dwReserved, pbind);

    This->binding = pbind;
    IBinding_AddRef(This->binding);

    return S_OK;
}

static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface,
       LONG *pnPriority)
{
    BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
    FIXME("(%p)->(%p)\n", This, pnPriority);
    return E_NOTIMPL;
}

static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallback *iface,
       DWORD reserved)
{
    BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
    FIXME("(%p)->(%d)\n", This, reserved);
    return E_NOTIMPL;
}

static DWORD get_http_status_code(IBinding *binding)
{
    IWinInetHttpInfo *http_info;
    DWORD status, size = sizeof(DWORD);
    HRESULT hres;

    hres = IBinding_QueryInterface(binding, &IID_IWinInetHttpInfo, (void**)&http_info);
    if(FAILED(hres))
        return HTTP_STATUS_OK;

    hres = IWinInetHttpInfo_QueryInfo(http_info, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER,
            &status, &size, NULL, NULL);
    IWinInetHttpInfo_Release(http_info);

    if(FAILED(hres))
        return HTTP_STATUS_OK;
    return status;
}

static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface,
        ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
{
    BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
    DWORD status_code;

    TRACE("(%p)->(%d %d %d %s)\n", This, ulProgress, ulProgressMax, ulStatusCode,
          debugstr_w(szStatusText));

    switch(ulStatusCode) {
    case BINDSTATUS_REDIRECTING:
        return set_dochost_url(This->doc_host, szStatusText);
    case BINDSTATUS_BEGINDOWNLOADDATA:
        set_status_text(This, ulStatusCode, szStatusText);
        status_code = get_http_status_code(This->binding);
        if(status_code != HTTP_STATUS_OK)
            handle_navigation_error(This->doc_host, status_code, This->url, NULL);
        return S_OK;

    case BINDSTATUS_FINDINGRESOURCE:
    case BINDSTATUS_ENDDOWNLOADDATA:
    case BINDSTATUS_SENDINGREQUEST:
        set_status_text(This, ulStatusCode, szStatusText);
        return S_OK;

    case BINDSTATUS_CONNECTING:
    case BINDSTATUS_CACHEFILENAMEAVAILABLE:
    case BINDSTATUS_CLASSIDAVAILABLE:
    case BINDSTATUS_MIMETYPEAVAILABLE:
    case BINDSTATUS_BEGINSYNCOPERATION:
    case BINDSTATUS_ENDSYNCOPERATION:
        return S_OK;
    default:
        FIXME("status code %u\n", ulStatusCode);
    }

    return S_OK;
}

void handle_navigation_error(DocHost* doc_host, HRESULT hres, BSTR url, IHTMLWindow2 *win2)
{
    VARIANT var_status_code, var_frame_name, var_url;
    DISPPARAMS dispparams;
    VARIANTARG params[5];
    VARIANT_BOOL cancel = VARIANT_FALSE;

    dispparams.cArgs = 5;
    dispparams.cNamedArgs = 0;
    dispparams.rgdispidNamedArgs = NULL;
    dispparams.rgvarg = params;

    V_VT(params) = VT_BOOL|VT_BYREF;
    V_BOOLREF(params) = &cancel;

    V_VT(params+1) = VT_VARIANT|VT_BYREF;
    V_VARIANTREF(params+1) = &var_status_code;
    V_VT(&var_status_code) = VT_I4;
    V_I4(&var_status_code) = hres;

    V_VT(params+2) = VT_VARIANT|VT_BYREF;
    V_VARIANTREF(params+2) = &var_frame_name;
    V_VT(&var_frame_name) = VT_BSTR;
    if(win2) {
        hres = IHTMLWindow2_get_name(win2, &V_BSTR(&var_frame_name));
        if(FAILED(hres))
            V_BSTR(&var_frame_name) = NULL;
    } else
        V_BSTR(&var_frame_name) = NULL;

    V_VT(params+3) = VT_VARIANT|VT_BYREF;
    V_VARIANTREF(params+3) = &var_url;
    V_VT(&var_url) = VT_BSTR;
    V_BSTR(&var_url) = url;

    V_VT(params+4) = VT_DISPATCH;
    V_DISPATCH(params+4) = (IDispatch*)doc_host->wb;

    call_sink(doc_host->cps.wbe2, DISPID_NAVIGATEERROR, &dispparams);
    SysFreeString(V_BSTR(&var_frame_name));

    if(!cancel)
        FIXME("Navigate to error page\n");
}

static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface,
        HRESULT hresult, LPCWSTR szError)
{
    BindStatusCallback *This = impl_from_IBindStatusCallback(iface);

    TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));

    set_status_text(This, 0, emptyW);

    if(!This->doc_host)
        return S_OK;

    if(!This->doc_host->olecmd)
        notify_download_state(This->doc_host, FALSE);
    if(FAILED(hresult))
        handle_navigation_error(This->doc_host, hresult, This->url, NULL);

    IOleClientSite_Release(&This->doc_host->IOleClientSite_iface);
    This->doc_host = NULL;

    IBinding_Release(This->binding);
    This->binding = NULL;

    return S_OK;
}

static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface,
        DWORD *grfBINDF, BINDINFO *pbindinfo)
{
    BindStatusCallback *This = impl_from_IBindStatusCallback(iface);

    TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);

    *grfBINDF = BINDF_ASYNCHRONOUS;

    if(This->post_data) {
        pbindinfo->dwBindVerb = BINDVERB_POST;

        pbindinfo->stgmedData.tymed = TYMED_HGLOBAL;
        pbindinfo->stgmedData.u.hGlobal = This->post_data;
        pbindinfo->cbstgmedData = This->post_data_len;
        pbindinfo->stgmedData.pUnkForRelease = (IUnknown*)&This->IBindStatusCallback_iface;
        IBindStatusCallback_AddRef(&This->IBindStatusCallback_iface);
    }

    return S_OK;
}

static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *iface,
        DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed)
{
    BindStatusCallback *This = impl_from_IBindStatusCallback(iface);
    FIXME("(%p)->(%08x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
    return E_NOTIMPL;
}

static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface,
        REFIID riid, IUnknown *punk)
{
    BindStatusCallback *This = impl_from_IBindStatusCallback(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), punk);

    return dochost_object_available(This->doc_host, punk);
}

static const IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
    BindStatusCallback_QueryInterface,
    BindStatusCallback_AddRef,
    BindStatusCallback_Release,
    BindStatusCallback_OnStartBinding,
    BindStatusCallback_GetPriority,
    BindStatusCallback_OnLowResource,
    BindStatusCallback_OnProgress,
    BindStatusCallback_OnStopBinding,
    BindStatusCallback_GetBindInfo,
    BindStatusCallback_OnDataAvailable,
    BindStatusCallback_OnObjectAvailable
};

static inline BindStatusCallback *impl_from_IHttpNegotiate(IHttpNegotiate *iface)
{
    return CONTAINING_RECORD(iface, BindStatusCallback, IHttpNegotiate_iface);
}

static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate *iface,
                                                   REFIID riid, void **ppv)
{
    BindStatusCallback *This = impl_from_IHttpNegotiate(iface);
    return IBindStatusCallback_QueryInterface(&This->IBindStatusCallback_iface, riid, ppv);
}

static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate *iface)
{
    BindStatusCallback *This = impl_from_IHttpNegotiate(iface);
    return IBindStatusCallback_AddRef(&This->IBindStatusCallback_iface);
}

static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate *iface)
{
    BindStatusCallback *This = impl_from_IHttpNegotiate(iface);
    return IBindStatusCallback_Release(&This->IBindStatusCallback_iface);
}

static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate *iface,
        LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
{
    BindStatusCallback *This = impl_from_IHttpNegotiate(iface);

    TRACE("(%p)->(%s %s %d %p)\n", This, debugstr_w(szURL), debugstr_w(szHeaders),
          dwReserved, pszAdditionalHeaders);

    if(This->headers) {
        int size = (strlenW(This->headers)+1)*sizeof(WCHAR);
        *pszAdditionalHeaders = CoTaskMemAlloc(size);
        memcpy(*pszAdditionalHeaders, This->headers, size);
    }

    return S_OK;
}

static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate *iface,
        DWORD dwResponseCode, LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders,
        LPWSTR *pszAdditionalRequestHeaders)
{
    BindStatusCallback *This = impl_from_IHttpNegotiate(iface);
    TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders),
          debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders);
    return S_OK;
}

static const IHttpNegotiateVtbl HttpNegotiateVtbl = {
    HttpNegotiate_QueryInterface,
    HttpNegotiate_AddRef,
    HttpNegotiate_Release,
    HttpNegotiate_BeginningTransaction,
    HttpNegotiate_OnResponse
};

static inline BindStatusCallback *impl_from_IHttpSecurity(IHttpSecurity *iface)
{
    return CONTAINING_RECORD(iface, BindStatusCallback, IHttpSecurity_iface);
}

static HRESULT WINAPI HttpSecurity_QueryInterface(IHttpSecurity *iface, REFIID riid, void **ppv)
{
    BindStatusCallback *This = impl_from_IHttpSecurity(iface);
    return IBindStatusCallback_QueryInterface(&This->IBindStatusCallback_iface, riid, ppv);
}

static ULONG WINAPI HttpSecurity_AddRef(IHttpSecurity *iface)
{
    BindStatusCallback *This = impl_from_IHttpSecurity(iface);
    return IBindStatusCallback_AddRef(&This->IBindStatusCallback_iface);
}

static ULONG WINAPI HttpSecurity_Release(IHttpSecurity *iface)
{
    BindStatusCallback *This = impl_from_IHttpSecurity(iface);
    return IBindStatusCallback_Release(&This->IBindStatusCallback_iface);
}

static HRESULT WINAPI HttpSecurity_GetWindow(IHttpSecurity *iface, REFGUID rguidReason, HWND *phwnd)
{
    BindStatusCallback *This = impl_from_IHttpSecurity(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(rguidReason), phwnd);

    if(!This->doc_host)
        return E_FAIL;

    *phwnd = This->doc_host->frame_hwnd;
    return S_OK;
}

static HRESULT WINAPI HttpSecurity_OnSecurityProblem(IHttpSecurity *iface, DWORD dwProblem)
{
    BindStatusCallback *This = impl_from_IHttpSecurity(iface);
    FIXME("(%p)->(%u)\n", This, dwProblem);
    return S_FALSE;
}

static const IHttpSecurityVtbl HttpSecurityVtbl = {
    HttpSecurity_QueryInterface,
    HttpSecurity_AddRef,
    HttpSecurity_Release,
    HttpSecurity_GetWindow,
    HttpSecurity_OnSecurityProblem
};

static BindStatusCallback *create_callback(DocHost *doc_host, LPCWSTR url, PBYTE post_data,
        ULONG post_data_len, LPCWSTR headers)
{
    BindStatusCallback *ret = heap_alloc(sizeof(BindStatusCallback));

    ret->IBindStatusCallback_iface.lpVtbl = &BindStatusCallbackVtbl;
    ret->IHttpNegotiate_iface.lpVtbl      = &HttpNegotiateVtbl;
    ret->IHttpSecurity_iface.lpVtbl       = &HttpSecurityVtbl;

    ret->ref = 1;
    ret->url = SysAllocString(url);
    ret->post_data = NULL;
    ret->post_data_len = post_data_len;
    ret->headers = headers ? SysAllocString(headers) : NULL;

    ret->doc_host = doc_host;
    IOleClientSite_AddRef(&doc_host->IOleClientSite_iface);

    ret->binding = NULL;

    if(post_data) {
        ret->post_data = GlobalAlloc(0, post_data_len);
        memcpy(ret->post_data, post_data, post_data_len);
    }

    return ret;
}

static void on_before_navigate2(DocHost *This, LPCWSTR url, SAFEARRAY *post_data, LPWSTR headers, VARIANT_BOOL *cancel)
{
    VARIANT var_url, var_flags, var_frame_name, var_post_data, var_post_data2, var_headers;
    DISPPARAMS dispparams;
    VARIANTARG params[7];
    WCHAR file_path[MAX_PATH];
    DWORD file_path_len = sizeof(file_path) / sizeof(*file_path);

    dispparams.cArgs = 7;
    dispparams.cNamedArgs = 0;
    dispparams.rgdispidNamedArgs = NULL;
    dispparams.rgvarg = params;

    This->busy = VARIANT_TRUE;

    V_VT(params) = VT_BOOL|VT_BYREF;
    V_BOOLREF(params) = cancel;

    V_VT(params+1) = (VT_BYREF|VT_VARIANT);
    V_VARIANTREF(params+1) = &var_headers;
    V_VT(&var_headers) = VT_BSTR;
    V_BSTR(&var_headers) = headers;

    V_VT(params+2) = (VT_BYREF|VT_VARIANT);
    V_VARIANTREF(params+2) = &var_post_data2;
    V_VT(&var_post_data2) = (VT_BYREF|VT_VARIANT);
    V_VARIANTREF(&var_post_data2) = &var_post_data;

    if(post_data) {
        V_VT(&var_post_data) = VT_UI1|VT_ARRAY;
        V_ARRAY(&var_post_data) = post_data;
    }else {
        V_VT(&var_post_data) = VT_EMPTY;
    }

    V_VT(params+3) = (VT_BYREF|VT_VARIANT);
    V_VARIANTREF(params+3) = &var_frame_name;
    V_VT(&var_frame_name) = VT_BSTR;
    V_BSTR(&var_frame_name) = NULL;

    V_VT(params+4) = (VT_BYREF|VT_VARIANT);
    V_VARIANTREF(params+4) = &var_flags;
    V_VT(&var_flags) = VT_I4;
    V_I4(&var_flags) = 0;

    V_VT(params+5) = (VT_BYREF|VT_VARIANT);
    V_VARIANTREF(params+5) = &var_url;
    V_VT(&var_url) = VT_BSTR;
    if(PathCreateFromUrlW(url, file_path, &file_path_len, 0) == S_OK)
        V_BSTR(&var_url) = SysAllocString(file_path);
    else
        V_BSTR(&var_url) = SysAllocString(url);

    V_VT(params+6) = (VT_DISPATCH);
    V_DISPATCH(params+6) = (IDispatch*)This->wb;

    call_sink(This->cps.wbe2, DISPID_BEFORENAVIGATE2, &dispparams);

    SysFreeString(V_BSTR(&var_url));
}

/* FIXME: urlmon should handle it */
static BOOL try_application_url(LPCWSTR url)
{
    SHELLEXECUTEINFOW exec_info;
    WCHAR app[64];
    HKEY hkey;
    DWORD res, type;
    HRESULT hres;

    static const WCHAR wszURLProtocol[] = {'U','R','L',' ','P','r','o','t','o','c','o','l',0};

    hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, app, sizeof(app)/sizeof(WCHAR), NULL, 0);
    if(FAILED(hres))
        return FALSE;

    res = RegOpenKeyW(HKEY_CLASSES_ROOT, app, &hkey);
    if(res != ERROR_SUCCESS)
        return FALSE;

    res = RegQueryValueExW(hkey, wszURLProtocol, NULL, &type, NULL, NULL);
    RegCloseKey(hkey);
    if(res != ERROR_SUCCESS || type != REG_SZ)
        return FALSE;

    TRACE("opening application %s\n", debugstr_w(app));

    memset(&exec_info, 0, sizeof(exec_info));
    exec_info.cbSize = sizeof(exec_info);
    exec_info.lpFile = url;
    exec_info.nShow = SW_SHOW;

    return ShellExecuteExW(&exec_info);
}

static HRESULT create_moniker(LPCWSTR url, IMoniker **mon)
{
    WCHAR new_url[INTERNET_MAX_URL_LENGTH];
    DWORD size;
    HRESULT hres;

    if(PathIsURLW(url))
        return CreateURLMoniker(NULL, url, mon);

    size = sizeof(new_url)/sizeof(WCHAR);
    hres = UrlApplySchemeW(url, new_url, &size, URL_APPLY_GUESSSCHEME | URL_APPLY_GUESSFILE | URL_APPLY_DEFAULT);
    TRACE("was %s got %s\n", debugstr_w(url), debugstr_w(new_url));
    if(FAILED(hres)) {
        WARN("UrlApplyScheme failed: %08x\n", hres);
        return hres;
    }

    return CreateURLMoniker(NULL, new_url, mon);
}

static HRESULT bind_to_object(DocHost *This, IMoniker *mon, LPCWSTR url, IBindCtx *bindctx,
                              IBindStatusCallback *callback)
{
    IUnknown *unk = NULL;
    WCHAR *display_name;
    HRESULT hres;

    if(mon) {
        IMoniker_AddRef(mon);
    }else {
        hres = create_moniker(url, &mon);
        if(FAILED(hres))
            return hres;
    }

    hres = IMoniker_GetDisplayName(mon, 0, NULL, &display_name);
    if(FAILED(hres)) {
        FIXME("GetDisplayName failed: %08x\n", hres);
        IMoniker_Release(mon);
        return hres;
    }

    hres = set_dochost_url(This, display_name);
    CoTaskMemFree(display_name);
    if(FAILED(hres)) {
        IMoniker_Release(mon);
        return hres;
    }

    IBindCtx_RegisterObjectParam(bindctx, (LPOLESTR)SZ_HTML_CLIENTSITE_OBJECTPARAM,
                                 (IUnknown*)&This->IOleClientSite_iface);

    hres = IMoniker_BindToObject(mon, bindctx, NULL, &IID_IUnknown, (void**)&unk);
    if(SUCCEEDED(hres)) {
        hres = S_OK;
        if(unk)
            IUnknown_Release(unk);
    }else if(try_application_url(url)) {
        hres = S_OK;
    }else {
        FIXME("BindToObject failed: %08x\n", hres);
    }

    IMoniker_Release(mon);
    return S_OK;
}

static void html_window_navigate(DocHost *This, IHTMLPrivateWindow *window, BSTR url, BSTR headers, SAFEARRAY *post_data)
{
    VARIANT headers_var, post_data_var;
    BSTR empty_str;
    HRESULT hres;

    hres = set_dochost_url(This, url);
    if(FAILED(hres))
        return;

    empty_str = SysAllocStringLen(NULL, 0);

    if(headers) {
        V_VT(&headers_var) = VT_BSTR;
        V_BSTR(&headers_var) = headers;
    }else {
        V_VT(&headers_var) = VT_EMPTY;
    }

    if(post_data) {
        V_VT(&post_data_var) = VT_UI1|VT_ARRAY;
        V_ARRAY(&post_data_var) = post_data;
    }else {
        V_VT(&post_data_var) = VT_EMPTY;
    }

    set_doc_state(This, READYSTATE_LOADING);
    hres = IHTMLPrivateWindow_SuperNavigate(window, url, empty_str, NULL, NULL, &post_data_var, &headers_var, 0);
    SysFreeString(empty_str);
    if(FAILED(hres))
        WARN("SuprtNavigate failed: %08x\n", hres);
}

typedef struct {
    task_header_t header;
    BSTR url;
    BSTR headers;
    SAFEARRAY *post_data;
    BOOL async_notif;
} task_doc_navigate_t;

static void doc_navigate_task_destr(task_header_t *t)
{
    task_doc_navigate_t *task = (task_doc_navigate_t*)t;

    SysFreeString(task->url);
    SysFreeString(task->headers);
    if(task->post_data)
        SafeArrayDestroy(task->post_data);
    heap_free(task);
}

static void doc_navigate_proc(DocHost *This, task_header_t *t)
{
    task_doc_navigate_t *task = (task_doc_navigate_t*)t;
    IHTMLPrivateWindow *priv_window;
    HRESULT hres;

    if(!This->doc_navigate) {
        ERR("Skip nav\n");
        return;
    }

    if(task->async_notif) {
        VARIANT_BOOL cancel = VARIANT_FALSE;
        on_before_navigate2(This, task->url, task->post_data, task->headers, &cancel);
        if(cancel) {
            TRACE("Navigation canceled\n");
            return;
        }
    }

    hres = IUnknown_QueryInterface(This->doc_navigate, &IID_IHTMLPrivateWindow, (void**)&priv_window);
    if(SUCCEEDED(hres)) {
        html_window_navigate(This, priv_window, task->url, task->headers, task->post_data);
        IHTMLPrivateWindow_Release(priv_window);
    }else {
        WARN("Could not get IHTMLPrivateWindow iface: %08x\n", hres);
    }
}

static HRESULT async_doc_navigate(DocHost *This, LPCWSTR url, LPCWSTR headers, PBYTE post_data, ULONG post_data_size,
        BOOL async_notif)
{
    task_doc_navigate_t *task;

    TRACE("%s\n", debugstr_w(url));

    task = heap_alloc_zero(sizeof(*task));
    if(!task)
        return E_OUTOFMEMORY;

    task->url = SysAllocString(url);
    if(!task->url) {
        doc_navigate_task_destr(&task->header);
        return E_OUTOFMEMORY;
    }

    if(headers) {
        task->headers = SysAllocString(headers);
        if(!task->headers) {
            doc_navigate_task_destr(&task->header);
            return E_OUTOFMEMORY;
        }
    }

    if(post_data) {
        task->post_data = SafeArrayCreateVector(VT_UI1, 0, post_data_size);
        if(!task->post_data) {
            doc_navigate_task_destr(&task->header);
            return E_OUTOFMEMORY;
        }

        memcpy(task->post_data->pvData, post_data, post_data_size);
    }

    if(!async_notif) {
        VARIANT_BOOL cancel = VARIANT_FALSE;

        on_before_navigate2(This, task->url, task->post_data, task->headers, &cancel);
        if(cancel) {
            TRACE("Navigation canceled\n");
            doc_navigate_task_destr(&task->header);
            return S_OK;
        }
    }

    task->async_notif = async_notif;
    abort_dochost_tasks(This, doc_navigate_proc);
    push_dochost_task(This, &task->header, doc_navigate_proc, doc_navigate_task_destr, FALSE);
    return S_OK;
}

static HRESULT navigate_bsc(DocHost *This, BindStatusCallback *bsc, IMoniker *mon)
{
    VARIANT_BOOL cancel = VARIANT_FALSE;
    SAFEARRAY *post_data = NULL;
    IBindCtx *bindctx;
    HRESULT hres;

    set_doc_state(This, READYSTATE_LOADING);

    if(bsc->post_data) {
        post_data = SafeArrayCreateVector(VT_UI1, 0, bsc->post_data_len);
        memcpy(post_data->pvData, post_data, bsc->post_data_len);
    }

    on_before_navigate2(This, bsc->url, post_data, bsc->headers, &cancel);
    if(post_data)
        SafeArrayDestroy(post_data);
    if(cancel) {
        FIXME("Navigation canceled\n");
        return S_OK;
    }

    notify_download_state(This, TRUE);
    on_commandstate_change(This, CSC_NAVIGATEBACK, FALSE);
    on_commandstate_change(This, CSC_NAVIGATEFORWARD, FALSE);

    if(This->document)
        deactivate_document(This);

    CreateAsyncBindCtx(0, &bsc->IBindStatusCallback_iface, 0, &bindctx);

    if(This->frame)
        IOleInPlaceFrame_EnableModeless(This->frame, FALSE);

    hres = bind_to_object(This, mon, bsc->url, bindctx, &bsc->IBindStatusCallback_iface);

    if(This->frame)
        IOleInPlaceFrame_EnableModeless(This->frame, TRUE);

    IBindCtx_Release(bindctx);

    return hres;
}

typedef struct {
    task_header_t header;
    BindStatusCallback *bsc;
} task_navigate_bsc_t;

static void navigate_bsc_task_destr(task_header_t *t)
{
    task_navigate_bsc_t *task = (task_navigate_bsc_t*)t;

    IBindStatusCallback_Release(&task->bsc->IBindStatusCallback_iface);
    heap_free(task);
}

static void navigate_bsc_proc(DocHost *This, task_header_t *t)
{
    task_navigate_bsc_t *task = (task_navigate_bsc_t*)t;

    if(!This->hwnd)
        create_doc_view_hwnd(This);

    navigate_bsc(This, task->bsc, NULL);
}


HRESULT navigate_url(DocHost *This, LPCWSTR url, const VARIANT *Flags,
                     const VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
{
    SAFEARRAY *post_array = NULL;
    PBYTE post_data = NULL;
    ULONG post_data_len = 0;
    LPWSTR headers = NULL;
    HRESULT hres = S_OK;

    TRACE("navigating to %s\n", debugstr_w(url));

    if((Flags && V_VT(Flags) != VT_EMPTY && V_VT(Flags) != VT_ERROR)
       || (TargetFrameName && V_VT(TargetFrameName) != VT_EMPTY && V_VT(TargetFrameName) != VT_ERROR))
        FIXME("Unsupported args (Flags %s; TargetFrameName %s)\n", debugstr_variant(Flags), debugstr_variant(TargetFrameName));

    if(PostData) {
        if(V_VT(PostData) & VT_ARRAY)
            post_array = V_ISBYREF(PostData) ? *V_ARRAYREF(PostData) : V_ARRAY(PostData);
        else
            WARN("Invalid post data %s\n", debugstr_variant(PostData));
    }

    if(post_array) {
        LONG elem_max;
        SafeArrayAccessData(post_array, (void**)&post_data);
        SafeArrayGetUBound(post_array, 1, &elem_max);
        post_data_len = (elem_max+1) * SafeArrayGetElemsize(post_array);
    }

    if(Headers && V_VT(Headers) == VT_BSTR) {
        headers = V_BSTR(Headers);
        TRACE("Headers: %s\n", debugstr_w(headers));
    }

    set_doc_state(This, READYSTATE_LOADING);
    This->ready_state = READYSTATE_LOADING;

    if(This->doc_navigate) {
        WCHAR new_url[INTERNET_MAX_URL_LENGTH];

        if(PathIsURLW(url)) {
            new_url[0] = 0;
        }else {
            DWORD size;

            size = sizeof(new_url)/sizeof(WCHAR);
            hres = UrlApplySchemeW(url, new_url, &size,
                    URL_APPLY_GUESSSCHEME | URL_APPLY_GUESSFILE | URL_APPLY_DEFAULT);
            if(FAILED(hres)) {
                WARN("UrlApplyScheme failed: %08x\n", hres);
                new_url[0] = 0;
            }
        }

        hres = async_doc_navigate(This, *new_url ? new_url : url, headers, post_data,
                post_data_len, TRUE);
    }else {
        task_navigate_bsc_t *task;

        task = heap_alloc(sizeof(*task));
        task->bsc = create_callback(This, url, post_data, post_data_len, headers);
        push_dochost_task(This, &task->header, navigate_bsc_proc, navigate_bsc_task_destr, This->url == NULL);
    }

    if(post_data)
        SafeArrayUnaccessData(post_array);

    return hres;
}

static HRESULT navigate_hlink(DocHost *This, IMoniker *mon, IBindCtx *bindctx,
                              IBindStatusCallback *callback)
{
    IHttpNegotiate *http_negotiate;
    BindStatusCallback *bsc;
    PBYTE post_data = NULL;
    ULONG post_data_len = 0;
    LPWSTR headers = NULL, url;
    BINDINFO bindinfo;
    DWORD bindf = 0;
    HRESULT hres;

    TRACE("\n");

    hres = IMoniker_GetDisplayName(mon, 0, NULL, &url);
    if(FAILED(hres))
        FIXME("GetDisplayName failed: %08x\n", hres);

    hres = IBindStatusCallback_QueryInterface(callback, &IID_IHttpNegotiate,
                                              (void**)&http_negotiate);
    if(SUCCEEDED(hres)) {
        static const WCHAR null_string[] = {0};

        IHttpNegotiate_BeginningTransaction(http_negotiate, null_string, null_string, 0,
                                            &headers);
        IHttpNegotiate_Release(http_negotiate);
    }

    memset(&bindinfo, 0, sizeof(bindinfo));
    bindinfo.cbSize = sizeof(bindinfo);

    hres = IBindStatusCallback_GetBindInfo(callback, &bindf, &bindinfo);
    dump_BINDINFO(&bindinfo);
    if(bindinfo.dwBindVerb == BINDVERB_POST) {
        post_data_len = bindinfo.cbstgmedData;
        if(post_data_len)
            post_data = bindinfo.stgmedData.u.hGlobal;
    }

    if(This->doc_navigate) {
        hres = async_doc_navigate(This, url, headers, post_data, post_data_len, FALSE);
    }else {
        bsc = create_callback(This, url, post_data, post_data_len, headers);
        hres = navigate_bsc(This, bsc, mon);
        IBindStatusCallback_Release(&bsc->IBindStatusCallback_iface);
    }

    CoTaskMemFree(url);
    CoTaskMemFree(headers);
    ReleaseBindInfo(&bindinfo);

    return hres;
}

HRESULT go_home(DocHost *This)
{
    HKEY hkey;
    DWORD res, type, size;
    WCHAR wszPageName[MAX_PATH];
    static const WCHAR wszAboutBlank[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
    static const WCHAR wszStartPage[] = {'S','t','a','r','t',' ','P','a','g','e',0};
    static const WCHAR wszSubKey[] = {'S','o','f','t','w','a','r','e','\\',
                                      'M','i','c','r','o','s','o','f','t','\\',
                                      'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
                                      'M','a','i','n',0};

    res = RegOpenKeyW(HKEY_CURRENT_USER, wszSubKey, &hkey);
    if (res != ERROR_SUCCESS)
        return navigate_url(This, wszAboutBlank, NULL, NULL, NULL, NULL);

    size = sizeof(wszPageName);
    res = RegQueryValueExW(hkey, wszStartPage, NULL, &type, (LPBYTE)wszPageName, &size);
    RegCloseKey(hkey);
    if (res != ERROR_SUCCESS || type != REG_SZ)
        return navigate_url(This, wszAboutBlank, NULL, NULL, NULL, NULL);

    return navigate_url(This, wszPageName, NULL, NULL, NULL, NULL);
}

static HRESULT navigate_history(DocHost *This, unsigned travellog_pos)
{
    IPersistHistory *persist_history;
    travellog_entry_t *entry;
    LARGE_INTEGER li;
    HRESULT hres;

    if(!This->doc_navigate) {
        FIXME("unsupported doc_navigate FALSE\n");
        return E_NOTIMPL;
    }

    This->travellog.loading_pos = travellog_pos;
    entry = This->travellog.log + This->travellog.loading_pos;

    update_navigation_commands(This);

    if(!entry->stream)
        return async_doc_navigate(This, entry->url, NULL, NULL, 0, FALSE);

    hres = IUnknown_QueryInterface(This->document, &IID_IPersistHistory, (void**)&persist_history);
    if(FAILED(hres))
        return hres;

    li.QuadPart = 0;
    IStream_Seek(entry->stream, li, STREAM_SEEK_SET, NULL);

    hres = IPersistHistory_LoadHistory(persist_history, entry->stream, NULL);
    IPersistHistory_Release(persist_history);
    return hres;
}

HRESULT go_back(DocHost *This)
{
    if(!This->travellog.position) {
        WARN("No history available\n");
        return E_FAIL;
    }

    return navigate_history(This, This->travellog.position-1);
}

HRESULT go_forward(DocHost *This)
{
    if(This->travellog.position >= This->travellog.length) {
        WARN("No history available\n");
        return E_FAIL;
    }

    return navigate_history(This, This->travellog.position+1);
}

HRESULT get_location_url(DocHost *This, BSTR *ret)
{
    FIXME("semi-stub\n");

    *ret = This->url ? SysAllocString(This->url) : SysAllocStringLen(NULL, 0);
    if(!*ret)
        return E_OUTOFMEMORY;

    return This->url ? S_OK : S_FALSE;
}

static inline HlinkFrame *impl_from_IHlinkFrame(IHlinkFrame *iface)
{
    return CONTAINING_RECORD(iface, HlinkFrame, IHlinkFrame_iface);
}

static HRESULT WINAPI HlinkFrame_QueryInterface(IHlinkFrame *iface, REFIID riid, void **ppv)
{
    HlinkFrame *This = impl_from_IHlinkFrame(iface);
    return IUnknown_QueryInterface(This->outer, riid, ppv);
}

static ULONG WINAPI HlinkFrame_AddRef(IHlinkFrame *iface)
{
    HlinkFrame *This = impl_from_IHlinkFrame(iface);
    return IUnknown_AddRef(This->outer);
}

static ULONG WINAPI HlinkFrame_Release(IHlinkFrame *iface)
{
    HlinkFrame *This = impl_from_IHlinkFrame(iface);
    return IUnknown_Release(This->outer);
}

static HRESULT WINAPI HlinkFrame_SetBrowseContext(IHlinkFrame *iface,
                                                  IHlinkBrowseContext *pihlbc)
{
    HlinkFrame *This = impl_from_IHlinkFrame(iface);
    FIXME("(%p)->(%p)\n", This, pihlbc);
    return E_NOTIMPL;
}

static HRESULT WINAPI HlinkFrame_GetBrowseContext(IHlinkFrame *iface,
                                                  IHlinkBrowseContext **ppihlbc)
{
    HlinkFrame *This = impl_from_IHlinkFrame(iface);
    FIXME("(%p)->(%p)\n", This, ppihlbc);
    return E_NOTIMPL;
}

static HRESULT WINAPI HlinkFrame_Navigate(IHlinkFrame *iface, DWORD grfHLNF, LPBC pbc,
                                          IBindStatusCallback *pibsc, IHlink *pihlNavigate)
{
    HlinkFrame *This = impl_from_IHlinkFrame(iface);
    IMoniker *mon;
    LPWSTR location = NULL;

    TRACE("(%p)->(%08x %p %p %p)\n", This, grfHLNF, pbc, pibsc, pihlNavigate);

    if(grfHLNF)
        FIXME("unsupported grfHLNF=%08x\n", grfHLNF);

    /* Windows calls GetTargetFrameName here. */

    IHlink_GetMonikerReference(pihlNavigate, 1, &mon, &location);

    if(location) {
        FIXME("location = %s\n", debugstr_w(location));
        CoTaskMemFree(location);
    }

    /* Windows calls GetHlinkSite here */

    if(grfHLNF & HLNF_OPENINNEWWINDOW) {
        FIXME("Not supported HLNF_OPENINNEWWINDOW\n");
        return E_NOTIMPL;
    }

    return navigate_hlink(This->doc_host, mon, pbc, pibsc);
}

static HRESULT WINAPI HlinkFrame_OnNavigate(IHlinkFrame *iface, DWORD grfHLNF,
        IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName, DWORD dwreserved)
{
    HlinkFrame *This = impl_from_IHlinkFrame(iface);
    FIXME("(%p)->(%08x %p %s %s %d)\n", This, grfHLNF, pimkTarget, debugstr_w(pwzLocation),
          debugstr_w(pwzFriendlyName), dwreserved);
    return E_NOTIMPL;
}

static HRESULT WINAPI HlinkFrame_UpdateHlink(IHlinkFrame *iface, ULONG uHLID,
        IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName)
{
    HlinkFrame *This = impl_from_IHlinkFrame(iface);
    FIXME("(%p)->(%u %p %s %s)\n", This, uHLID, pimkTarget, debugstr_w(pwzLocation),
          debugstr_w(pwzFriendlyName));
    return E_NOTIMPL;
}

static const IHlinkFrameVtbl HlinkFrameVtbl = {
    HlinkFrame_QueryInterface,
    HlinkFrame_AddRef,
    HlinkFrame_Release,
    HlinkFrame_SetBrowseContext,
    HlinkFrame_GetBrowseContext,
    HlinkFrame_Navigate,
    HlinkFrame_OnNavigate,
    HlinkFrame_UpdateHlink
};

static inline HlinkFrame *impl_from_ITargetFrame(ITargetFrame *iface)
{
    return CONTAINING_RECORD(iface, HlinkFrame, ITargetFrame_iface);
}

static HRESULT WINAPI TargetFrame_QueryInterface(ITargetFrame *iface, REFIID riid, void **ppv)
{
    HlinkFrame *This = impl_from_ITargetFrame(iface);
    return IUnknown_QueryInterface(This->outer, riid, ppv);
}

static ULONG WINAPI TargetFrame_AddRef(ITargetFrame *iface)
{
    HlinkFrame *This = impl_from_ITargetFrame(iface);
    return IUnknown_AddRef(This->outer);
}

static ULONG WINAPI TargetFrame_Release(ITargetFrame *iface)
{
    HlinkFrame *This = impl_from_ITargetFrame(iface);
    return IUnknown_Release(This->outer);
}

static HRESULT WINAPI TargetFrame_SetFrameName(ITargetFrame *iface, LPCWSTR pszFrameName)
{
    HlinkFrame *This = impl_from_ITargetFrame(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(pszFrameName));
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame_GetFrameName(ITargetFrame *iface, LPWSTR *ppszFrameName)
{
    HlinkFrame *This = impl_from_ITargetFrame(iface);
    FIXME("(%p)->(%p)\n", This, ppszFrameName);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame_GetParentFrame(ITargetFrame *iface, IUnknown **ppunkParent)
{
    HlinkFrame *This = impl_from_ITargetFrame(iface);
    FIXME("(%p)->(%p)\n", This, ppunkParent);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame_FindFrame(ITargetFrame *iface, LPCWSTR pszTargetName,
        IUnknown *ppunkContextFrame, DWORD dwFlags, IUnknown **ppunkTargetFrame)
{
    HlinkFrame *This = impl_from_ITargetFrame(iface);
    FIXME("(%p)->(%s %p %x %p)\n", This, debugstr_w(pszTargetName),
            ppunkContextFrame, dwFlags, ppunkTargetFrame);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame_SetFrameSrc(ITargetFrame *iface, LPCWSTR pszFrameSrc)
{
    HlinkFrame *This = impl_from_ITargetFrame(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(pszFrameSrc));
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame_GetFrameSrc(ITargetFrame *iface, LPWSTR *ppszFrameSrc)
{
    HlinkFrame *This = impl_from_ITargetFrame(iface);
    FIXME("(%p)->(%p)\n", This, ppszFrameSrc);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame_GetFramesContainer(ITargetFrame *iface, IOleContainer **ppContainer)
{
    HlinkFrame *This = impl_from_ITargetFrame(iface);
    FIXME("(%p)->(%p)\n", This, ppContainer);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame_SetFrameOptions(ITargetFrame *iface, DWORD dwFlags)
{
    HlinkFrame *This = impl_from_ITargetFrame(iface);
    FIXME("(%p)->(%x)\n", This, dwFlags);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame_GetFrameOptions(ITargetFrame *iface, DWORD *pdwFlags)
{
    HlinkFrame *This = impl_from_ITargetFrame(iface);
    FIXME("(%p)->(%p)\n", This, pdwFlags);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame_SetFrameMargins(ITargetFrame *iface, DWORD dwWidth, DWORD dwHeight)
{
    HlinkFrame *This = impl_from_ITargetFrame(iface);
    FIXME("(%p)->(%d %d)\n", This, dwWidth, dwHeight);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame_GetFrameMargins(ITargetFrame *iface, DWORD *pdwWidth, DWORD *pdwHeight)
{
    HlinkFrame *This = impl_from_ITargetFrame(iface);
    FIXME("(%p)->(%p %p)\n", This, pdwWidth, pdwHeight);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame_RemoteNavigate(ITargetFrame *iface, ULONG cLength, ULONG *pulData)
{
    HlinkFrame *This = impl_from_ITargetFrame(iface);
    FIXME("(%p)->(%u %p)\n", This, cLength, pulData);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame_OnChildFrameActivate(ITargetFrame *iface, IUnknown *pUnkChildFrame)
{
    HlinkFrame *This = impl_from_ITargetFrame(iface);
    FIXME("(%p)->(%p)\n", This, pUnkChildFrame);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame_OnChildFrameDeactivate(ITargetFrame *iface, IUnknown *pUnkChildFrame)
{
    HlinkFrame *This = impl_from_ITargetFrame(iface);
    FIXME("(%p)->(%p)\n", This, pUnkChildFrame);
    return E_NOTIMPL;
}

static const ITargetFrameVtbl TargetFrameVtbl = {
    TargetFrame_QueryInterface,
    TargetFrame_AddRef,
    TargetFrame_Release,
    TargetFrame_SetFrameName,
    TargetFrame_GetFrameName,
    TargetFrame_GetParentFrame,
    TargetFrame_FindFrame,
    TargetFrame_SetFrameSrc,
    TargetFrame_GetFrameSrc,
    TargetFrame_GetFramesContainer,
    TargetFrame_SetFrameOptions,
    TargetFrame_GetFrameOptions,
    TargetFrame_SetFrameMargins,
    TargetFrame_GetFrameMargins,
    TargetFrame_RemoteNavigate,
    TargetFrame_OnChildFrameActivate,
    TargetFrame_OnChildFrameDeactivate
};

static inline HlinkFrame *impl_from_ITargetFrame2(ITargetFrame2 *iface)
{
    return CONTAINING_RECORD(iface, HlinkFrame, ITargetFrame2_iface);
}

static HRESULT WINAPI TargetFrame2_QueryInterface(ITargetFrame2 *iface, REFIID riid, void **ppv)
{
    HlinkFrame *This = impl_from_ITargetFrame2(iface);
    return IUnknown_QueryInterface(This->outer, riid, ppv);
}

static ULONG WINAPI TargetFrame2_AddRef(ITargetFrame2 *iface)
{
    HlinkFrame *This = impl_from_ITargetFrame2(iface);
    return IUnknown_AddRef(This->outer);
}

static ULONG WINAPI TargetFrame2_Release(ITargetFrame2 *iface)
{
    HlinkFrame *This = impl_from_ITargetFrame2(iface);
    return IUnknown_Release(This->outer);
}

static HRESULT WINAPI TargetFrame2_SetFrameName(ITargetFrame2 *iface, LPCWSTR pszFrameName)
{
    HlinkFrame *This = impl_from_ITargetFrame2(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(pszFrameName));
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame2_GetFrameName(ITargetFrame2 *iface, LPWSTR *ppszFrameName)
{
    HlinkFrame *This = impl_from_ITargetFrame2(iface);
    FIXME("(%p)->(%p)\n", This, ppszFrameName);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame2_GetParentFrame(ITargetFrame2 *iface, IUnknown **ppunkParent)
{
    HlinkFrame *This = impl_from_ITargetFrame2(iface);
    FIXME("(%p)->(%p)\n", This, ppunkParent);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame2_SetFrameSrc(ITargetFrame2 *iface, LPCWSTR pszFrameSrc)
{
    HlinkFrame *This = impl_from_ITargetFrame2(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(pszFrameSrc));
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame2_GetFrameSrc(ITargetFrame2 *iface, LPWSTR *ppszFrameSrc)
{
    HlinkFrame *This = impl_from_ITargetFrame2(iface);
    FIXME("(%p)->()\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame2_GetFramesContainer(ITargetFrame2 *iface, IOleContainer **ppContainer)
{
    HlinkFrame *This = impl_from_ITargetFrame2(iface);
    FIXME("(%p)->(%p)\n", This, ppContainer);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame2_SetFrameOptions(ITargetFrame2 *iface, DWORD dwFlags)
{
    HlinkFrame *This = impl_from_ITargetFrame2(iface);
    FIXME("(%p)->(%x)\n", This, dwFlags);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame2_GetFrameOptions(ITargetFrame2 *iface, DWORD *pdwFlags)
{
    HlinkFrame *This = impl_from_ITargetFrame2(iface);
    FIXME("(%p)->(%p)\n", This, pdwFlags);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame2_SetFrameMargins(ITargetFrame2 *iface, DWORD dwWidth, DWORD dwHeight)
{
    HlinkFrame *This = impl_from_ITargetFrame2(iface);
    FIXME("(%p)->(%d %d)\n", This, dwWidth, dwHeight);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame2_GetFrameMargins(ITargetFrame2 *iface, DWORD *pdwWidth, DWORD *pdwHeight)
{
    HlinkFrame *This = impl_from_ITargetFrame2(iface);
    FIXME("(%p)->(%p %p)\n", This, pdwWidth, pdwHeight);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame2_FindFrame(ITargetFrame2 *iface, LPCWSTR pszTargetName, DWORD dwFlags, IUnknown **ppunkTargetFrame)
{
    HlinkFrame *This = impl_from_ITargetFrame2(iface);
    FIXME("(%p)->(%s %x %p)\n", This, debugstr_w(pszTargetName), dwFlags, ppunkTargetFrame);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFrame2_GetTargetAlias(ITargetFrame2 *iface, LPCWSTR pszTargetName, LPWSTR *ppszTargetAlias)
{
    HlinkFrame *This = impl_from_ITargetFrame2(iface);
    FIXME("(%p)->(%s %p)\n", This, debugstr_w(pszTargetName), ppszTargetAlias);
    return E_NOTIMPL;
}

static const ITargetFrame2Vtbl TargetFrame2Vtbl = {
    TargetFrame2_QueryInterface,
    TargetFrame2_AddRef,
    TargetFrame2_Release,
    TargetFrame2_SetFrameName,
    TargetFrame2_GetFrameName,
    TargetFrame2_GetParentFrame,
    TargetFrame2_SetFrameSrc,
    TargetFrame2_GetFrameSrc,
    TargetFrame2_GetFramesContainer,
    TargetFrame2_SetFrameOptions,
    TargetFrame2_GetFrameOptions,
    TargetFrame2_SetFrameMargins,
    TargetFrame2_GetFrameMargins,
    TargetFrame2_FindFrame,
    TargetFrame2_GetTargetAlias
};

static inline HlinkFrame *impl_from_ITargetFramePriv2(ITargetFramePriv2 *iface)
{
    return CONTAINING_RECORD(iface, HlinkFrame, ITargetFramePriv2_iface);
}

static HRESULT WINAPI TargetFramePriv2_QueryInterface(ITargetFramePriv2 *iface, REFIID riid, void **ppv)
{
    HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
    return IUnknown_QueryInterface(This->outer, riid, ppv);
}

static ULONG WINAPI TargetFramePriv2_AddRef(ITargetFramePriv2 *iface)
{
    HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
    return IUnknown_AddRef(This->outer);
}

static ULONG WINAPI TargetFramePriv2_Release(ITargetFramePriv2 *iface)
{
    HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
    return IUnknown_Release(This->outer);
}

static HRESULT WINAPI TargetFramePriv2_FindFrameDownwards(ITargetFramePriv2 *iface,
        LPCWSTR pszTargetName, DWORD dwFlags, IUnknown **ppunkTargetFrame)
{
    HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
    FIXME("(%p)->(%s %x %p)\n", This, debugstr_w(pszTargetName), dwFlags, ppunkTargetFrame);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFramePriv2_FindFrameInContext(ITargetFramePriv2 *iface,
        LPCWSTR pszTargetName, IUnknown *punkContextFrame, DWORD dwFlags, IUnknown **ppunkTargetFrame)
{
    HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
    FIXME("(%p)->(%s %p %x %p)\n", This, debugstr_w(pszTargetName), punkContextFrame, dwFlags, ppunkTargetFrame);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFramePriv2_OnChildFrameActivate(ITargetFramePriv2 *iface, IUnknown *pUnkChildFrame)
{
    HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
    FIXME("(%p)->(%p)\n", This, pUnkChildFrame);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFramePriv2_OnChildFrameDeactivate(ITargetFramePriv2 *iface, IUnknown *pUnkChildFrame)
{
    HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
    FIXME("(%p)->(%p)\n", This, pUnkChildFrame);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFramePriv2_NavigateHack(ITargetFramePriv2 *iface, DWORD grfHLNF, LPBC pbc,
        IBindStatusCallback *pibsc, LPCWSTR pszTargetName, LPCWSTR pszUrl, LPCWSTR pszLocation)
{
    HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
    FIXME("(%p)->(%x %p %p %s %s %s)\n", This, grfHLNF, pbc, pibsc, debugstr_w(pszTargetName),
          debugstr_w(pszUrl), debugstr_w(pszLocation));
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFramePriv2_FindBrowserByIndex(ITargetFramePriv2 *iface, DWORD dwID, IUnknown **ppunkBrowser)
{
    HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
    FIXME("(%p)->(%d %p)\n", This, dwID, ppunkBrowser);
    return E_NOTIMPL;
}

static HRESULT WINAPI TargetFramePriv2_AggregatedNavigation2(ITargetFramePriv2 *iface, DWORD grfHLNF, LPBC pbc,
        IBindStatusCallback *pibsc, LPCWSTR pszTargetName, IUri *pUri, LPCWSTR pszLocation)
{
    HlinkFrame *This = impl_from_ITargetFramePriv2(iface);
    IMoniker *mon;
    HRESULT hres;

    TRACE("(%p)->(%x %p %p %s %p %s)\n", This, grfHLNF, pbc, pibsc, debugstr_w(pszTargetName),
          pUri, debugstr_w(pszLocation));

    /*
     * NOTE: This is an undocumented function. It seems to be working the way it's implemented,
     * but I couldn't get its tests working. It's used by mshtml to load content in a new
     * instance of browser.
     */

    hres = CreateURLMonikerEx2(NULL, pUri, &mon, 0);
    if(FAILED(hres))
        return hres;

    hres = navigate_hlink(This->doc_host, mon, pbc, pibsc);
    IMoniker_Release(mon);
    return hres;
}

static const ITargetFramePriv2Vtbl TargetFramePriv2Vtbl = {
    TargetFramePriv2_QueryInterface,
    TargetFramePriv2_AddRef,
    TargetFramePriv2_Release,
    TargetFramePriv2_FindFrameDownwards,
    TargetFramePriv2_FindFrameInContext,
    TargetFramePriv2_OnChildFrameActivate,
    TargetFramePriv2_OnChildFrameDeactivate,
    TargetFramePriv2_NavigateHack,
    TargetFramePriv2_FindBrowserByIndex,
    TargetFramePriv2_AggregatedNavigation2
};

static inline HlinkFrame *impl_from_IWebBrowserPriv2IE9(IWebBrowserPriv2IE9 *iface)
{
    return CONTAINING_RECORD(iface, HlinkFrame, IWebBrowserPriv2IE9_iface);
}

static HRESULT WINAPI WebBrowserPriv2IE9_QueryInterface(IWebBrowserPriv2IE9 *iface, REFIID riid, void **ppv)
{
    HlinkFrame *This = impl_from_IWebBrowserPriv2IE9(iface);
    return IUnknown_QueryInterface(This->outer, riid, ppv);
}

static ULONG WINAPI WebBrowserPriv2IE9_AddRef(IWebBrowserPriv2IE9 *iface)
{
    HlinkFrame *This = impl_from_IWebBrowserPriv2IE9(iface);
    return IUnknown_AddRef(This->outer);
}

static ULONG WINAPI WebBrowserPriv2IE9_Release(IWebBrowserPriv2IE9 *iface)
{
    HlinkFrame *This = impl_from_IWebBrowserPriv2IE9(iface);
    return IUnknown_Release(This->outer);
}

static HRESULT WINAPI WebBrowserPriv2IE9_NavigateWithBindCtx2(IWebBrowserPriv2IE9 *iface, IUri *uri, VARIANT *flags,
        VARIANT *target_frame, VARIANT *post_data, VARIANT *headers, IBindCtx *bind_ctx, LPOLESTR url_fragment, DWORD unused)
{
    HlinkFrame *This = impl_from_IWebBrowserPriv2IE9(iface);
    FIXME("(%p)->(%p %s %s %s %s %p %s)\n", This, uri, debugstr_variant(flags), debugstr_variant(target_frame),
          debugstr_variant(post_data), debugstr_variant(headers), bind_ctx, debugstr_w(url_fragment));
    return E_NOTIMPL;
}

static const IWebBrowserPriv2IE9Vtbl WebBrowserPriv2IE9Vtbl = {
    WebBrowserPriv2IE9_QueryInterface,
    WebBrowserPriv2IE9_AddRef,
    WebBrowserPriv2IE9_Release,
    WebBrowserPriv2IE9_NavigateWithBindCtx2
};

BOOL HlinkFrame_QI(HlinkFrame *This, REFIID riid, void **ppv)
{
    if(IsEqualGUID(&IID_IHlinkFrame, riid)) {
        TRACE("(%p)->(IID_IHlinkFrame %p)\n", This, ppv);
        *ppv = &This->IHlinkFrame_iface;
    }else if(IsEqualGUID(&IID_ITargetFrame, riid)) {
        TRACE("(%p)->(IID_ITargetFrame %p)\n", This, ppv);
        *ppv = &This->ITargetFrame_iface;
    }else if(IsEqualGUID(&IID_ITargetFrame2, riid)) {
        TRACE("(%p)->(IID_ITargetFrame2 %p)\n", This, ppv);
        *ppv = &This->ITargetFrame2_iface;
    }else if(IsEqualGUID(&IID_ITargetFramePriv, riid)) {
        TRACE("(%p)->(IID_ITargetFramePriv %p)\n", This, ppv);
        *ppv = &This->ITargetFramePriv2_iface;
    }else if(IsEqualGUID(&IID_ITargetFramePriv2, riid)) {
        TRACE("(%p)->(IID_ITargetFramePriv2 %p)\n", This, ppv);
        *ppv = &This->ITargetFramePriv2_iface;
    }else if(IsEqualGUID(&IID_IWebBrowserPriv2IE9, riid)) {
        TRACE("(%p)->(IID_IWebBrowserPriv2IE9 %p)\n", This, ppv);
        *ppv = &This->IWebBrowserPriv2IE9_iface;
    }else {
        return FALSE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return TRUE;
}

void HlinkFrame_Init(HlinkFrame *This, IUnknown *outer, DocHost *doc_host)
{
    This->IHlinkFrame_iface.lpVtbl = &HlinkFrameVtbl;
    This->ITargetFrame_iface.lpVtbl = &TargetFrameVtbl;
    This->ITargetFrame2_iface.lpVtbl = &TargetFrame2Vtbl;
    This->ITargetFramePriv2_iface.lpVtbl = &TargetFramePriv2Vtbl;
    This->IWebBrowserPriv2IE9_iface.lpVtbl = &WebBrowserPriv2IE9Vtbl;

    This->outer = outer;
    This->doc_host = doc_host;
}
