/*
 * 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);
        return hres;
    }

    hres = set_dochost_url(This, display_name);
    CoTaskMemFree(display_name);
    if(FAILED(hres))
        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;
}
