/*
 * Copyright 2017 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 COBJMACROS
#define NONAMELESSUNION

#include <assert.h>

#include "mimeole.h"
#include "inetcomm_private.h"

#include "wine/debug.h"
#include "wine/unicode.h"

WINE_DEFAULT_DEBUG_CHANNEL(inetcomm);

typedef struct {
    IUnknown IUnknown_inner;
    IInternetProtocol IInternetProtocol_iface;
    IInternetProtocolInfo IInternetProtocolInfo_iface;

    LONG ref;
    IUnknown *outer_unk;

    WCHAR *location;
    IStream *stream;
    IInternetProtocolSink *sink;
} MimeHtmlProtocol;

typedef struct {
    const WCHAR *mhtml;
    size_t mhtml_len;
    const WCHAR *location;
} mhtml_url_t;

typedef struct {
    IBindStatusCallback IBindStatusCallback_iface;

    LONG ref;

    MimeHtmlProtocol *protocol;
    HRESULT status;
    IStream *stream;
    WCHAR url[1];
} MimeHtmlBinding;

static const WCHAR mhtml_prefixW[] = {'m','h','t','m','l',':'};
static const WCHAR mhtml_separatorW[] = {'!','x','-','u','s','c',':'};

static inline LPWSTR heap_strdupW(LPCWSTR str)
{
    LPWSTR ret = NULL;

    if(str) {
        DWORD size;

        size = (strlenW(str)+1)*sizeof(WCHAR);
        ret = heap_alloc(size);
        if(ret)
            memcpy(ret, str, size);
    }

    return ret;
}

static HRESULT parse_mhtml_url(const WCHAR *url, mhtml_url_t *r)
{
    const WCHAR *p;

    if(strncmpiW(url, mhtml_prefixW, sizeof(mhtml_prefixW)/sizeof(WCHAR)))
        return E_FAIL;

    r->mhtml = url + sizeof(mhtml_prefixW)/sizeof(WCHAR);
    p = strchrW(r->mhtml, '!');
    if(p) {
        r->mhtml_len = p - r->mhtml;
        /* FIXME: We handle '!' and '!x-usc:' in URLs as the same thing. Those should not be the same. */
        if(!strncmpW(p, mhtml_separatorW, sizeof(mhtml_separatorW)/sizeof(WCHAR)))
            p += sizeof(mhtml_separatorW)/sizeof(WCHAR);
        else
            p++;
    }else {
        r->mhtml_len = strlenW(r->mhtml);
    }

    r->location = p;
    return S_OK;
}

static HRESULT report_result(MimeHtmlProtocol *protocol, HRESULT result)
{
    if(protocol->sink) {
        IInternetProtocolSink_ReportResult(protocol->sink, result, ERROR_SUCCESS, NULL);
        IInternetProtocolSink_Release(protocol->sink);
        protocol->sink = NULL;
    }

    return result;
}

static HRESULT on_mime_message_available(MimeHtmlProtocol *protocol, IMimeMessage *mime_message)
{
    FINDBODY find = {NULL};
    IMimeBody *mime_body;
    PROPVARIANT value;
    HBODY body;
    HRESULT hres;

    hres = IMimeMessage_FindFirst(mime_message, &find, &body);
    if(FAILED(hres))
        return report_result(protocol, hres);

    if(protocol->location) {
        BOOL found = FALSE;
        do {
            hres = IMimeMessage_FindNext(mime_message, &find, &body);
            if(FAILED(hres)) {
                WARN("location %s not found\n", debugstr_w(protocol->location));
                return report_result(protocol, hres);
            }

            value.vt = VT_LPWSTR;
            hres = IMimeMessage_GetBodyProp(mime_message, body, "content-location", 0, &value);
            if(hres == MIME_E_NOT_FOUND)
                continue;
            if(FAILED(hres))
                return report_result(protocol, hres);

            found = !strcmpW(protocol->location, value.u.pwszVal);
            PropVariantClear(&value);
        }while(!found);
    }else {
        hres = IMimeMessage_FindNext(mime_message, &find, &body);
        if(FAILED(hres)) {
            WARN("location %s not found\n", debugstr_w(protocol->location));
            return report_result(protocol, hres);
        }
    }

    hres = IMimeMessage_BindToObject(mime_message, body, &IID_IMimeBody, (void**)&mime_body);
    if(FAILED(hres))
        return report_result(protocol, hres);

    value.vt = VT_LPWSTR;
    hres = IMimeBody_GetProp(mime_body, "content-type", 0, &value);
    if(SUCCEEDED(hres)) {
        hres = IInternetProtocolSink_ReportProgress(protocol->sink, BINDSTATUS_MIMETYPEAVAILABLE, value.u.pwszVal);
        PropVariantClear(&value);
    }

    /* FIXME: Create and report cache file. */

    hres = IMimeBody_GetData(mime_body, IET_DECODED, &protocol->stream);
    if(FAILED(hres))
        return report_result(protocol, hres);

    IInternetProtocolSink_ReportData(protocol->sink, BSCF_FIRSTDATANOTIFICATION
                                     | BSCF_INTERMEDIATEDATANOTIFICATION
                                     | BSCF_LASTDATANOTIFICATION
                                     | BSCF_DATAFULLYAVAILABLE
                                     | BSCF_AVAILABLEDATASIZEUNKNOWN, 0, 0);

    return report_result(protocol, S_OK);
}

static HRESULT load_mime_message(IStream *stream, IMimeMessage **ret)
{
    IMimeMessage *mime_message;
    HRESULT hres;

    hres = MimeMessage_create(NULL, (void**)&mime_message);
    if(FAILED(hres))
        return hres;

    IMimeMessage_InitNew(mime_message);

    hres = IMimeMessage_Load(mime_message, stream);
    if(FAILED(hres)) {
        IMimeMessage_Release(mime_message);
        return hres;
    }

    *ret = mime_message;
    return S_OK;
}

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

static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *iface,
        REFIID riid, void **ppv)
{
    MimeHtmlBinding *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 {
        TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
        *ppv = NULL;
        return E_NOINTERFACE;
    }

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

static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface)
{
    MimeHtmlBinding *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)
{
    MimeHtmlBinding *This = impl_from_IBindStatusCallback(iface);
    LONG ref = InterlockedDecrement(&This->ref);

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

    if(!ref) {
        if(This->protocol)
            IInternetProtocol_Release(&This->protocol->IInternetProtocol_iface);
        if(This->stream)
            IStream_Release(This->stream);
        heap_free(This);
    }

    return ref;
}

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

    TRACE("(%p)->(%x %p)\n", This, dwReserved, pib);

    assert(!This->stream);
    return CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
}

static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
{
    return E_NOTIMPL;
}

static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD dwReserved)
{
    return E_NOTIMPL;
}

static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
        ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
{
    MimeHtmlBinding *This = impl_from_IBindStatusCallback(iface);
    TRACE("(%p)->(%u/%u %u %s)\n", This, ulProgress, ulProgressMax, ulStatusCode, debugstr_w(szStatusText));
    return S_OK;
}

static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
{
    MimeHtmlBinding *This = impl_from_IBindStatusCallback(iface);
    IMimeMessage *mime_message = NULL;

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

    if(SUCCEEDED(hresult)) {
        hresult = load_mime_message(This->stream, &mime_message);
        IStream_Release(This->stream);
        This->stream = NULL;
    }

    This->status = hresult;

    if(mime_message)
        on_mime_message_available(This->protocol, mime_message);
    else
        report_result(This->protocol, hresult);

    if(mime_message)
        IMimeMessage_Release(mime_message);
    IInternetProtocol_Release(&This->protocol->IInternetProtocol_iface);
    This->protocol = NULL;
    return S_OK;
}

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

    TRACE("(%p)\n", This);

    *grfBINDF = BINDF_ASYNCHRONOUS;
    return S_OK;
}

static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
        DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
{
    MimeHtmlBinding *This = impl_from_IBindStatusCallback(iface);
    BYTE buf[4*1024];
    DWORD read;
    HRESULT hres;

    TRACE("(%p)\n", This);

    assert(pstgmed->tymed == TYMED_ISTREAM);

    while(1) {
        hres = IStream_Read(pstgmed->u.pstm, buf, sizeof(buf), &read);
        if(FAILED(hres))
            return hres;
        if(!read)
            break;
        hres = IStream_Write(This->stream, buf, read, NULL);
        if(FAILED(hres))
            return hres;
    }
    return S_OK;
}

static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface,
        REFIID riid, IUnknown* punk)
{
    ERR("\n");
    return E_NOTIMPL;
}

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 MimeHtmlProtocol *impl_from_IUnknown(IUnknown *iface)
{
    return CONTAINING_RECORD(iface, MimeHtmlProtocol, IUnknown_inner);
}

static HRESULT WINAPI MimeHtmlProtocol_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
{
    MimeHtmlProtocol *This = impl_from_IUnknown(iface);

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
        *ppv = &This->IInternetProtocol_iface;
    }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
        TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
        *ppv = &This->IInternetProtocol_iface;
    }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
        TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
        *ppv = &This->IInternetProtocol_iface;
    }else if(IsEqualGUID(&IID_IInternetProtocolInfo, riid)) {
        TRACE("(%p)->(IID_IInternetProtocolInfo %p)\n", This, ppv);
        *ppv = &This->IInternetProtocolInfo_iface;
    }else {
        FIXME("unknown interface %s\n", debugstr_guid(riid));
        *ppv = NULL;
        return E_NOINTERFACE;
    }

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

static ULONG WINAPI MimeHtmlProtocol_AddRef(IUnknown *iface)
{
    MimeHtmlProtocol *This = impl_from_IUnknown(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI MimeHtmlProtocol_Release(IUnknown *iface)
{
    MimeHtmlProtocol *This = impl_from_IUnknown(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

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

    if(!ref) {
        if(This->sink)
            IInternetProtocolSink_Release(This->sink);
        if(This->stream)
            IStream_Release(This->stream);
        heap_free(This->location);
        heap_free(This);
    }

    return ref;
}

static const IUnknownVtbl MimeHtmlProtocolInnerVtbl = {
    MimeHtmlProtocol_QueryInterface,
    MimeHtmlProtocol_AddRef,
    MimeHtmlProtocol_Release
};

static inline MimeHtmlProtocol *impl_from_IInternetProtocol(IInternetProtocol *iface)
{
    return CONTAINING_RECORD(iface, MimeHtmlProtocol, IInternetProtocol_iface);
}

static HRESULT WINAPI InternetProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
    return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
}

static ULONG WINAPI InternetProtocol_AddRef(IInternetProtocol *iface)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
    return IUnknown_AddRef(This->outer_unk);
}

static ULONG WINAPI InternetProtocol_Release(IInternetProtocol *iface)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
    return IUnknown_Release(This->outer_unk);
}

static HRESULT WINAPI MimeHtmlProtocol_Start(IInternetProtocol *iface, const WCHAR *szUrl,
        IInternetProtocolSink* pOIProtSink, IInternetBindInfo* pOIBindInfo,
        DWORD grfPI, HANDLE_PTR dwReserved)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
    BINDINFO bindinfo = { sizeof(bindinfo) };
    MimeHtmlBinding *binding;
    IBindCtx *bind_ctx;
    IStream *stream;
    mhtml_url_t url;
    DWORD bindf = 0;
    IMoniker *mon;
    HRESULT hres;

    TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink, pOIBindInfo, grfPI, dwReserved);

    hres = parse_mhtml_url(szUrl, &url);
    if(FAILED(hres))
        return hres;

    if(url.location && !(This->location = heap_strdupW(url.location)))
        return E_OUTOFMEMORY;

    hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bindf, &bindinfo);
    if(FAILED(hres)) {
        WARN("GetBindInfo failed: %08x\n", hres);
        return hres;
    }
    if((bindf & (BINDF_ASYNCHRONOUS|BINDF_FROMURLMON|BINDF_NEEDFILE)) != (BINDF_ASYNCHRONOUS|BINDF_FROMURLMON|BINDF_NEEDFILE))
        FIXME("unsupported bindf %x\n", bindf);

    IInternetProtocolSink_AddRef(This->sink = pOIProtSink);

    binding = heap_alloc(FIELD_OFFSET(MimeHtmlBinding,  url[url.mhtml_len+1]));
    if(!binding)
        return E_OUTOFMEMORY;
    memcpy(binding->url, url.mhtml, url.mhtml_len*sizeof(WCHAR));
    binding->url[url.mhtml_len] = 0;

    hres = CreateURLMoniker(NULL, binding->url, &mon);
    if(FAILED(hres)) {
        heap_free(binding);
        return hres;
    }

    binding->IBindStatusCallback_iface.lpVtbl = &BindStatusCallbackVtbl;
    binding->ref = 1;
    binding->status = E_PENDING;
    binding->stream = NULL;
    binding->protocol = NULL;

    hres = CreateAsyncBindCtx(0, &binding->IBindStatusCallback_iface, NULL, &bind_ctx);
    if(FAILED(hres)) {
        IMoniker_Release(mon);
        IBindStatusCallback_Release(&binding->IBindStatusCallback_iface);
        return hres;
    }

    IInternetProtocol_AddRef(&This->IInternetProtocol_iface);
    binding->protocol = This;

    hres = IMoniker_BindToStorage(mon, bind_ctx, NULL, &IID_IStream, (void**)&stream);
    IBindCtx_Release(bind_ctx);
    IMoniker_Release(mon);
    if(stream)
        IStream_Release(stream);
    hres = binding->status;
    IBindStatusCallback_Release(&binding->IBindStatusCallback_iface);
    if(FAILED(hres) && hres != E_PENDING)
        report_result(This, hres);
    return hres;
}

static HRESULT WINAPI MimeHtmlProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
    FIXME("(%p)->(%p)\n", This, pProtocolData);
    return E_NOTIMPL;
}

static HRESULT WINAPI MimeHtmlProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason, DWORD dwOptions)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
    FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
    return E_NOTIMPL;
}

static HRESULT WINAPI MimeHtmlProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
    TRACE("(%p)->(%08x)\n", This, dwOptions);
    return S_OK;
}

static HRESULT WINAPI MimeHtmlProtocol_Suspend(IInternetProtocol *iface)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI MimeHtmlProtocol_Resume(IInternetProtocol *iface)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI MimeHtmlProtocol_Read(IInternetProtocol *iface, void* pv, ULONG cb, ULONG* pcbRead)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
    ULONG read = 0;
    HRESULT hres;

    TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);

    hres = IStream_Read(This->stream, pv, cb, &read);
    if(pcbRead)
        *pcbRead = read;
    if(hres != S_OK)
        return hres;

    return read ? S_OK : S_FALSE;
}

static HRESULT WINAPI MimeHtmlProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
        DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
    FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
    return E_NOTIMPL;
}

static HRESULT WINAPI MimeHtmlProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
    FIXME("(%p)->(%d)\n", This, dwOptions);
    return S_OK;
}

static HRESULT WINAPI MimeHtmlProtocol_UnlockRequest(IInternetProtocol *iface)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
    FIXME("(%p)\n", This);
    return S_OK;
}

static const IInternetProtocolVtbl MimeHtmlProtocolVtbl = {
    InternetProtocol_QueryInterface,
    InternetProtocol_AddRef,
    InternetProtocol_Release,
    MimeHtmlProtocol_Start,
    MimeHtmlProtocol_Continue,
    MimeHtmlProtocol_Abort,
    MimeHtmlProtocol_Terminate,
    MimeHtmlProtocol_Suspend,
    MimeHtmlProtocol_Resume,
    MimeHtmlProtocol_Read,
    MimeHtmlProtocol_Seek,
    MimeHtmlProtocol_LockRequest,
    MimeHtmlProtocol_UnlockRequest
};

static inline MimeHtmlProtocol *impl_from_IInternetProtocolInfo(IInternetProtocolInfo *iface)
{
    return CONTAINING_RECORD(iface, MimeHtmlProtocol, IInternetProtocolInfo_iface);
}

static HRESULT WINAPI MimeHtmlProtocolInfo_QueryInterface(IInternetProtocolInfo *iface, REFIID riid, void **ppv)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocolInfo(iface);
    return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
}

static ULONG WINAPI MimeHtmlProtocolInfo_AddRef(IInternetProtocolInfo *iface)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocolInfo(iface);
    return IUnknown_AddRef(This->outer_unk);
}

static ULONG WINAPI MimeHtmlProtocolInfo_Release(IInternetProtocolInfo *iface)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocolInfo(iface);
    return IUnknown_Release(This->outer_unk);
}

static HRESULT WINAPI MimeHtmlProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
        PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
        DWORD* pcchResult, DWORD dwReserved)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocolInfo(iface);
    FIXME("(%p)->(%s %d %x %p %d %p %d)\n", This, debugstr_w(pwzUrl), ParseAction,
          dwParseFlags, pwzResult, cchResult, pcchResult, dwReserved);
    return INET_E_DEFAULT_ACTION;
}

static HRESULT WINAPI MimeHtmlProtocolInfo_CombineUrl(IInternetProtocolInfo *iface,
        LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags, LPWSTR pwzResult,
        DWORD cchResult, DWORD* pcchResult, DWORD dwReserved)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocolInfo(iface);
    size_t len = sizeof(mhtml_prefixW)/sizeof(WCHAR);
    mhtml_url_t url;
    WCHAR *p;
    HRESULT hres;

    TRACE("(%p)->(%s %s %08x %p %d %p %d)\n", This, debugstr_w(pwzBaseUrl),
          debugstr_w(pwzRelativeUrl), dwCombineFlags, pwzResult, cchResult,
          pcchResult, dwReserved);

    hres = parse_mhtml_url(pwzBaseUrl, &url);
    if(FAILED(hres))
        return hres;

    if(!strncmpiW(pwzRelativeUrl, mhtml_prefixW, sizeof(mhtml_prefixW)/sizeof(WCHAR))) {
        FIXME("Relative URL is mhtml protocol\n");
        return INET_E_USE_DEFAULT_PROTOCOLHANDLER;
    }

    len += url.mhtml_len;
    if(*pwzRelativeUrl)
        len += strlenW(pwzRelativeUrl) + sizeof(mhtml_separatorW)/sizeof(WCHAR);
    if(len >= cchResult) {
        *pcchResult = 0;
        return E_FAIL;
    }

    memcpy(pwzResult, mhtml_prefixW, sizeof(mhtml_prefixW));
    p = pwzResult + sizeof(mhtml_prefixW)/sizeof(WCHAR);
    memcpy(p, url.mhtml, url.mhtml_len*sizeof(WCHAR));
    p += url.mhtml_len;
    if(*pwzRelativeUrl) {
        memcpy(p, mhtml_separatorW, sizeof(mhtml_separatorW));
        p += sizeof(mhtml_separatorW)/sizeof(WCHAR);
        strcpyW(p, pwzRelativeUrl);
    }else {
        *p = 0;
    }

    *pcchResult = len;
    return S_OK;
}

static HRESULT WINAPI MimeHtmlProtocolInfo_CompareUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl1,
        LPCWSTR pwzUrl2, DWORD dwCompareFlags)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocolInfo(iface);
    FIXME("(%p)->(%s %s %08x)\n", This, debugstr_w(pwzUrl1), debugstr_w(pwzUrl2), dwCompareFlags);
    return E_NOTIMPL;
}

static HRESULT WINAPI MimeHtmlProtocolInfo_QueryInfo(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
        QUERYOPTION QueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD* pcbBuf,
        DWORD dwReserved)
{
    MimeHtmlProtocol *This = impl_from_IInternetProtocolInfo(iface);
    FIXME("(%p)->(%s %08x %08x %p %d %p %d)\n", This, debugstr_w(pwzUrl), QueryOption, dwQueryFlags, pBuffer,
          cbBuffer, pcbBuf, dwReserved);
    return INET_E_USE_DEFAULT_PROTOCOLHANDLER;
}

static const IInternetProtocolInfoVtbl MimeHtmlProtocolInfoVtbl = {
    MimeHtmlProtocolInfo_QueryInterface,
    MimeHtmlProtocolInfo_AddRef,
    MimeHtmlProtocolInfo_Release,
    MimeHtmlProtocolInfo_ParseUrl,
    MimeHtmlProtocolInfo_CombineUrl,
    MimeHtmlProtocolInfo_CompareUrl,
    MimeHtmlProtocolInfo_QueryInfo
};

HRESULT MimeHtmlProtocol_create(IUnknown *outer, void **obj)
{
    MimeHtmlProtocol *protocol;

    protocol = heap_alloc(sizeof(*protocol));
    if(!protocol)
        return E_OUTOFMEMORY;

    protocol->IUnknown_inner.lpVtbl = &MimeHtmlProtocolInnerVtbl;
    protocol->IInternetProtocol_iface.lpVtbl = &MimeHtmlProtocolVtbl;
    protocol->IInternetProtocolInfo_iface.lpVtbl = &MimeHtmlProtocolInfoVtbl;
    protocol->ref = 1;
    protocol->outer_unk = outer ? outer : &protocol->IUnknown_inner;
    protocol->location = NULL;
    protocol->stream = NULL;
    protocol->sink = NULL;

    *obj = &protocol->IUnknown_inner;
    return S_OK;
}
