/*
 * Copyright 2005 Jacek Caban
 *
 * 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
 */

#include "config.h"

#include <stdarg.h>
#include <stdio.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"

#include "wine/debug.h"

#include "mshtml_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(mshtml);

/********************************************************************
 * common ProtocolFactory implementation
 */

typedef struct {
    IInternetProtocolInfo IInternetProtocolInfo_iface;
    IClassFactory         IClassFactory_iface;
} ProtocolFactory;

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

static HRESULT WINAPI InternetProtocolInfo_QueryInterface(IInternetProtocolInfo *iface, REFIID riid, void **ppv)
{
    ProtocolFactory *This = impl_from_IInternetProtocolInfo(iface);

    *ppv = NULL;
    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
        *ppv = &This->IInternetProtocolInfo_iface;
    }else if(IsEqualGUID(&IID_IInternetProtocolInfo, riid)) {
        TRACE("(%p)->(IID_IInternetProtocolInfo %p)\n", This, ppv);
        *ppv = &This->IInternetProtocolInfo_iface;
    }else if(IsEqualGUID(&IID_IClassFactory, riid)) {
        TRACE("(%p)->(IID_IClassFactory %p)\n", This, ppv);
        *ppv = &This->IClassFactory_iface;
    }

    if(!*ppv) {
        WARN("unknown interface %s\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

    IInternetProtocolInfo_AddRef(iface);
    return S_OK;
}

static ULONG WINAPI InternetProtocolInfo_AddRef(IInternetProtocolInfo *iface)
{
    TRACE("(%p)\n", iface);
    return 2;
}

static ULONG WINAPI InternetProtocolInfo_Release(IInternetProtocolInfo *iface)
{
    TRACE("(%p)\n", iface);
    return 1;
}

static HRESULT WINAPI InternetProtocolInfo_CombineUrl(IInternetProtocolInfo *iface,
        LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags, LPWSTR pwzResult,
        DWORD cchResult, DWORD* pcchResult, DWORD dwReserved)
{
    TRACE("%p)->(%s %s %08x %p %d %p %d)\n", iface, debugstr_w(pwzBaseUrl),
            debugstr_w(pwzRelativeUrl), dwCombineFlags, pwzResult, cchResult,
            pcchResult, dwReserved);

    return INET_E_USE_DEFAULT_PROTOCOLHANDLER;
}

static HRESULT WINAPI InternetProtocolInfo_CompareUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl1,
        LPCWSTR pwzUrl2, DWORD dwCompareFlags)
{
    TRACE("%p)->(%s %s %08x)\n", iface, debugstr_w(pwzUrl1), debugstr_w(pwzUrl2), dwCompareFlags);
    return E_NOTIMPL;
}

static inline ProtocolFactory *impl_from_IClassFactory(IClassFactory *iface)
{
    return CONTAINING_RECORD(iface, ProtocolFactory, IClassFactory_iface);
}

static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
{
    ProtocolFactory *This = impl_from_IClassFactory(iface);
    return IInternetProtocolInfo_QueryInterface(&This->IInternetProtocolInfo_iface, riid, ppv);
}

static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
{
    ProtocolFactory *This = impl_from_IClassFactory(iface);
    return IInternetProtocolInfo_AddRef(&This->IInternetProtocolInfo_iface);
}

static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
{
    ProtocolFactory *This = impl_from_IClassFactory(iface);
    return IInternetProtocolInfo_Release(&This->IInternetProtocolInfo_iface);
}

static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
{
    TRACE("(%p)->(%x)\n", iface, dolock);
    return S_OK;
}

/********************************************************************
 * AboutProtocol implementation
 */

typedef struct {
    IInternetProtocol IInternetProtocol_iface;

    LONG ref;

    BYTE *data;
    ULONG data_len;
    ULONG cur;

    IUnknown *pUnkOuter;
} AboutProtocol;

static inline AboutProtocol *AboutProtocol_from_IInternetProtocol(IInternetProtocol *iface)
{
    return CONTAINING_RECORD(iface, AboutProtocol, IInternetProtocol_iface);
}

static HRESULT WINAPI AboutProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
{
    AboutProtocol *This = AboutProtocol_from_IInternetProtocol(iface);

    *ppv = NULL;

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
        if(This->pUnkOuter)
            return IUnknown_QueryInterface(This->pUnkOuter, riid, ppv);
        *ppv = &This->IInternetProtocol_iface;
    }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
        TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", iface, ppv);
        *ppv = &This->IInternetProtocol_iface;
    }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
        TRACE("(%p)->(IID_IInternetProtocol %p)\n", iface, ppv);
        *ppv = &This->IInternetProtocol_iface;
    }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
        FIXME("IServiceProvider is not implemented\n");
        return E_NOINTERFACE;
    }

    if(!*ppv) {
        TRACE("unknown interface %s\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

    IInternetProtocol_AddRef(iface);
    return S_OK;
}

static ULONG WINAPI AboutProtocol_AddRef(IInternetProtocol *iface)
{
    AboutProtocol *This = AboutProtocol_from_IInternetProtocol(iface);
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p) ref=%d\n", iface, ref);
    return This->pUnkOuter ? IUnknown_AddRef(This->pUnkOuter) : ref;
}

static ULONG WINAPI AboutProtocol_Release(IInternetProtocol *iface)
{
    AboutProtocol *This = AboutProtocol_from_IInternetProtocol(iface);
    IUnknown *pUnkOuter = This->pUnkOuter;
    ULONG ref = InterlockedDecrement(&This->ref);

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

    if(!ref) {
        heap_free(This->data);
        heap_free(This);
    }

    return pUnkOuter ? IUnknown_Release(pUnkOuter) : ref;
}

static HRESULT WINAPI AboutProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
        IInternetProtocolSink* pOIProtSink, IInternetBindInfo* pOIBindInfo,
        DWORD grfPI, HANDLE_PTR dwReserved)
{
    AboutProtocol *This = AboutProtocol_from_IInternetProtocol(iface);
    BINDINFO bindinfo;
    DWORD grfBINDF = 0;
    LPCWSTR text = NULL;
    DWORD data_len;
    BYTE *data;
    HRESULT hres;

    static const WCHAR html_begin[] = {0xfeff,'<','H','T','M','L','>',0};
    static const WCHAR html_end[] = {'<','/','H','T','M','L','>',0};
    static const WCHAR wszBlank[] = {'b','l','a','n','k',0};
    static const WCHAR wszAbout[] = {'a','b','o','u','t',':'};
    static const WCHAR wszTextHtml[] = {'t','e','x','t','/','h','t','m','l',0};

    /* NOTE:
     * the about protocol seems not to work as I would expect. It creates html document
     * for a given url, eg. about:some_text -> <HTML>some_text</HTML> except for the case when
     * some_text = "blank", when document is blank (<HTML></HMTL>). The same happens
     * when the url does not have "about:" in the beginning.
     */

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

    memset(&bindinfo, 0, sizeof(bindinfo));
    bindinfo.cbSize = sizeof(BINDINFO);
    hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo);
    if(FAILED(hres))
        return hres;
    ReleaseBindInfo(&bindinfo);

    TRACE("bindf %x\n", grfBINDF);

    if(strlenW(szUrl)>=sizeof(wszAbout)/sizeof(WCHAR) && !memcmp(wszAbout, szUrl, sizeof(wszAbout))) {
        text = szUrl + sizeof(wszAbout)/sizeof(WCHAR);
        if(!strcmpW(wszBlank, text))
            text = NULL;
    }

    data_len = sizeof(html_begin)+sizeof(html_end)-sizeof(WCHAR)
        + (text ? strlenW(text)*sizeof(WCHAR) : 0);
    data = heap_alloc(data_len);
    if(!data)
        return E_OUTOFMEMORY;

    heap_free(This->data);
    This->data = data;
    This->data_len = data_len;

    memcpy(This->data, html_begin, sizeof(html_begin));
    if(text)
        strcatW((LPWSTR)This->data, text);
    strcatW((LPWSTR)This->data, html_end);
    
    This->cur = 0;

    IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, wszTextHtml);

    IInternetProtocolSink_ReportData(pOIProtSink,
            BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE,
            This->data_len, This->data_len);

    IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);

    return S_OK;
}

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

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

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

static HRESULT WINAPI AboutProtocol_Suspend(IInternetProtocol *iface)
{
    AboutProtocol *This = AboutProtocol_from_IInternetProtocol(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI AboutProtocol_Resume(IInternetProtocol *iface)
{
    AboutProtocol *This = AboutProtocol_from_IInternetProtocol(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI AboutProtocol_Read(IInternetProtocol *iface, void* pv, ULONG cb, ULONG* pcbRead)
{
    AboutProtocol *This = AboutProtocol_from_IInternetProtocol(iface);

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

    if(!This->data)
        return E_FAIL;

    *pcbRead = (cb > This->data_len-This->cur ? This->data_len-This->cur : cb);

    if(!*pcbRead)
        return S_FALSE;

    memcpy(pv, This->data+This->cur, *pcbRead);
    This->cur += *pcbRead;

    return S_OK;
}

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

static HRESULT WINAPI AboutProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
{
    AboutProtocol *This = AboutProtocol_from_IInternetProtocol(iface);

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

    return S_OK;
}

static HRESULT WINAPI AboutProtocol_UnlockRequest(IInternetProtocol *iface)
{
    AboutProtocol *This = AboutProtocol_from_IInternetProtocol(iface);

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

    return S_OK;
}

static const IInternetProtocolVtbl AboutProtocolVtbl = {
    AboutProtocol_QueryInterface,
    AboutProtocol_AddRef,
    AboutProtocol_Release,
    AboutProtocol_Start,
    AboutProtocol_Continue,
    AboutProtocol_Abort,
    AboutProtocol_Terminate,
    AboutProtocol_Suspend,
    AboutProtocol_Resume,
    AboutProtocol_Read,
    AboutProtocol_Seek,
    AboutProtocol_LockRequest,
    AboutProtocol_UnlockRequest
};

static HRESULT WINAPI AboutProtocolFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter,
        REFIID riid, void **ppv)
{
    AboutProtocol *ret;
    HRESULT hres = S_OK;

    TRACE("(%p)->(%p %s %p)\n", iface, pUnkOuter, debugstr_guid(riid), ppv);

    ret = heap_alloc(sizeof(AboutProtocol));
    ret->IInternetProtocol_iface.lpVtbl = &AboutProtocolVtbl;
    ret->ref = 0;

    ret->data = NULL;
    ret->data_len = 0;
    ret->cur = 0;
    ret->pUnkOuter = pUnkOuter;

    if(pUnkOuter) {
        ret->ref = 1;
        if(IsEqualGUID(&IID_IUnknown, riid))
            *ppv = &ret->IInternetProtocol_iface;
        else
            hres = E_INVALIDARG;
    }else {
        hres = IInternetProtocol_QueryInterface(&ret->IInternetProtocol_iface, riid, ppv);
    }

    if(FAILED(hres))
        heap_free(ret);

    return hres;
}

static HRESULT WINAPI AboutProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
        PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
        DWORD* pcchResult, DWORD dwReserved)
{
    TRACE("%p)->(%s %d %08x %p %d %p %d)\n", iface, debugstr_w(pwzUrl), ParseAction,
            dwParseFlags, pwzResult, cchResult, pcchResult, dwReserved);

    if(ParseAction == PARSE_SECURITY_URL) {
        unsigned int len = strlenW(pwzUrl)+1;

        *pcchResult = len;
        if(len > cchResult)
            return S_FALSE;

        memcpy(pwzResult, pwzUrl, len*sizeof(WCHAR));
        return S_OK;
    }

    if(ParseAction == PARSE_DOMAIN) {
        if(!pcchResult)
            return E_POINTER;

        if(pwzUrl)
            *pcchResult = strlenW(pwzUrl)+1;
        else
            *pcchResult = 1;
        return E_FAIL;
    }

    return INET_E_DEFAULT_ACTION;
}

static HRESULT WINAPI AboutProtocolInfo_QueryInfo(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
        QUERYOPTION QueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD* pcbBuf,
        DWORD dwReserved)
{
    TRACE("%p)->(%s %08x %08x %p %d %p %d)\n", iface, debugstr_w(pwzUrl), QueryOption, dwQueryFlags, pBuffer,
          cbBuffer, pcbBuf, dwReserved);

    switch(QueryOption) {
    case QUERY_CAN_NAVIGATE:
        return INET_E_USE_DEFAULT_PROTOCOLHANDLER;

    case QUERY_USES_NETWORK:
        if(!pBuffer || cbBuffer < sizeof(DWORD))
            return E_FAIL;

        *(DWORD*)pBuffer = 0;
        if(pcbBuf)
            *pcbBuf = sizeof(DWORD);

        break;

    case QUERY_IS_CACHED:
        FIXME("Unsupported option QUERY_IS_CACHED\n");
        return E_NOTIMPL;
    case QUERY_IS_INSTALLEDENTRY:
        FIXME("Unsupported option QUERY_IS_INSTALLEDENTRY\n");
        return E_NOTIMPL;
    case QUERY_IS_CACHED_OR_MAPPED:
        FIXME("Unsupported option QUERY_IS_CACHED_OR_MAPPED\n");
        return E_NOTIMPL;
    case QUERY_IS_SECURE:
        FIXME("Unsupported option QUERY_IS_SECURE\n");
        return E_NOTIMPL;
    case QUERY_IS_SAFE:
        FIXME("Unsupported option QUERY_IS_SAFE\n");
        return E_NOTIMPL;
    case QUERY_USES_HISTORYFOLDER:
        FIXME("Unsupported option QUERY_USES_HISTORYFOLDER\n");
        return E_FAIL;
    case QUERY_IS_CACHED_AND_USABLE_OFFLINE:
        FIXME("Unsupported option QUERY_IS_CACHED_AND_USABLE_OFFLINE\n");
        return E_NOTIMPL;
    default:
        return E_FAIL;
    }

    return S_OK;
}

static const IInternetProtocolInfoVtbl AboutProtocolInfoVtbl = {
    InternetProtocolInfo_QueryInterface,
    InternetProtocolInfo_AddRef,
    InternetProtocolInfo_Release,
    AboutProtocolInfo_ParseUrl,
    InternetProtocolInfo_CombineUrl,
    InternetProtocolInfo_CompareUrl,
    AboutProtocolInfo_QueryInfo
};

static const IClassFactoryVtbl AboutProtocolFactoryVtbl = {
    ClassFactory_QueryInterface,
    ClassFactory_AddRef,
    ClassFactory_Release,
    AboutProtocolFactory_CreateInstance,
    ClassFactory_LockServer
};

static ProtocolFactory AboutProtocolFactory = {
    { &AboutProtocolInfoVtbl },
    { &AboutProtocolFactoryVtbl }
};

/********************************************************************
 * ResProtocol implementation
 */

typedef struct {
    IInternetProtocol IInternetProtocol_iface;
    LONG ref;

    BYTE *data;
    ULONG data_len;
    ULONG cur;

    IUnknown *pUnkOuter;
} ResProtocol;

static inline ResProtocol *ResProtocol_from_IInternetProtocol(IInternetProtocol *iface)
{
    return CONTAINING_RECORD(iface, ResProtocol, IInternetProtocol_iface);
}

static HRESULT WINAPI ResProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
{
    ResProtocol *This = ResProtocol_from_IInternetProtocol(iface);

    *ppv = NULL;

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
        if(This->pUnkOuter)
            return IUnknown_QueryInterface(This->pUnkOuter, &IID_IUnknown, ppv);
        *ppv = &This->IInternetProtocol_iface;
    }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
        TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", iface, ppv);
        *ppv = &This->IInternetProtocol_iface;
    }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
        TRACE("(%p)->(IID_IInternetProtocol %p)\n", iface, ppv);
        *ppv = &This->IInternetProtocol_iface;
    }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
        FIXME("IServiceProvider is not implemented\n");
        return E_NOINTERFACE;
    }

    if(!*ppv) {
        TRACE("unknown interface %s\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

    IInternetProtocol_AddRef(iface);
    return S_OK;
}

static ULONG WINAPI ResProtocol_AddRef(IInternetProtocol *iface)
{
    ResProtocol *This = ResProtocol_from_IInternetProtocol(iface);
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p) ref=%d\n", iface, ref);
    return This->pUnkOuter ? IUnknown_AddRef(This->pUnkOuter) : ref;
}

static ULONG WINAPI ResProtocol_Release(IInternetProtocol *iface)
{
    ResProtocol *This = (ResProtocol*)iface;
    IUnknown *pUnkOuter = This->pUnkOuter;
    ULONG ref = InterlockedDecrement(&This->ref);

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

    if(!ref) {
        heap_free(This->data);
        heap_free(This);
    }

    return pUnkOuter ? IUnknown_Release(pUnkOuter) : ref;
}

static HRESULT WINAPI ResProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
        IInternetProtocolSink* pOIProtSink, IInternetBindInfo* pOIBindInfo,
        DWORD grfPI, HANDLE_PTR dwReserved)
{
    ResProtocol *This = ResProtocol_from_IInternetProtocol(iface);
    WCHAR *url_dll, *url_file, *url, *mime, *res_type = (LPWSTR)RT_HTML, *ptr;
    DWORD grfBINDF = 0, len;
    BINDINFO bindinfo;
    HMODULE hdll;
    HRSRC src;
    HRESULT hres;

    static const WCHAR wszRes[] = {'r','e','s',':','/','/'};

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

    memset(&bindinfo, 0, sizeof(bindinfo));
    bindinfo.cbSize = sizeof(BINDINFO);
    hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo);
    if(FAILED(hres))
        return hres;
    ReleaseBindInfo(&bindinfo);

    len = strlenW(szUrl)+16;
    url = heap_alloc(len*sizeof(WCHAR));
    hres = CoInternetParseUrl(szUrl, PARSE_ENCODE, 0, url, len, &len, 0);
    if(FAILED(hres)) {
        WARN("CoInternetParseUrl failed: %08x\n", hres);
        heap_free(url);
        IInternetProtocolSink_ReportResult(pOIProtSink, hres, 0, NULL);
        return hres;
    }

    if(len < sizeof(wszRes)/sizeof(wszRes[0]) || memcmp(url, wszRes, sizeof(wszRes))) {
        WARN("Wrong protocol of url: %s\n", debugstr_w(url));
        IInternetProtocolSink_ReportResult(pOIProtSink, E_INVALIDARG, 0, NULL);
        heap_free(url);
        return E_INVALIDARG;
    }

    url_dll = url + sizeof(wszRes)/sizeof(wszRes[0]);
    if(!(res_type = strchrW(url_dll, '/'))) {
        WARN("wrong url: %s\n", debugstr_w(url));
        IInternetProtocolSink_ReportResult(pOIProtSink, MK_E_SYNTAX, 0, NULL);
        heap_free(url);
        return MK_E_SYNTAX;
    }

    *res_type++ = 0;
    if ((url_file = strchrW(res_type, '/'))) {
        *url_file++ = 0;
    }else {
        url_file = res_type;
        res_type = (LPWSTR)RT_HTML;
    }

    /* Ignore query and hash parts. */
    if((ptr = strchrW(url_file, '?')))
        *ptr = 0;
    if(*url_file && (ptr = strchrW(url_file+1, '#')))
        *ptr = 0;

    hdll = LoadLibraryExW(url_dll, NULL, LOAD_LIBRARY_AS_DATAFILE);
    if(!hdll) {
        WARN("Could not open dll: %s\n", debugstr_w(url_dll));
        IInternetProtocolSink_ReportResult(pOIProtSink, HRESULT_FROM_WIN32(GetLastError()), 0, NULL);
        heap_free(url);
        return HRESULT_FROM_WIN32(GetLastError());
    }

    TRACE("trying to find resource type %s, name %s\n", debugstr_w(res_type), debugstr_w(url_file));

    src = FindResourceW(hdll, url_file, res_type);
    if(!src) {
        LPWSTR endpoint = NULL;
        DWORD file_id = strtolW(url_file, &endpoint, 10);
        if(endpoint == url_file+strlenW(url_file))
            src = FindResourceW(hdll, MAKEINTRESOURCEW(file_id), res_type);

        if(!src) {
            WARN("Could not find resource\n");
            IInternetProtocolSink_ReportResult(pOIProtSink,
                    HRESULT_FROM_WIN32(GetLastError()), 0, NULL);
            heap_free(url);
            return HRESULT_FROM_WIN32(GetLastError());
        }
    }

    if(This->data) {
        WARN("data already loaded\n");
        heap_free(This->data);
    }

    This->data_len = SizeofResource(hdll, src);
    This->data = heap_alloc(This->data_len);
    memcpy(This->data, LoadResource(hdll, src), This->data_len);
    This->cur = 0;

    FreeLibrary(hdll);

    hres = FindMimeFromData(NULL, url_file, This->data, This->data_len, NULL, 0, &mime, 0);
    heap_free(url);
    if(SUCCEEDED(hres)) {
        IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, mime);
        CoTaskMemFree(mime);
    }

    IInternetProtocolSink_ReportData(pOIProtSink,
            BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE,
            This->data_len, This->data_len);

    IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
    
    return S_OK;
}

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

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

static HRESULT WINAPI ResProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
{
    ResProtocol *This = ResProtocol_from_IInternetProtocol(iface);

    TRACE("(%p)->(%08x)\n", This, dwOptions);

    /* test show that we don't have to do anything here */
    return S_OK;
}

static HRESULT WINAPI ResProtocol_Suspend(IInternetProtocol *iface)
{
    ResProtocol *This = ResProtocol_from_IInternetProtocol(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI ResProtocol_Resume(IInternetProtocol *iface)
{
    ResProtocol *This = ResProtocol_from_IInternetProtocol(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI ResProtocol_Read(IInternetProtocol *iface, void* pv, ULONG cb, ULONG* pcbRead)
{
    ResProtocol *This = ResProtocol_from_IInternetProtocol(iface);

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

    if(!This->data)
        return E_FAIL;

    *pcbRead = (cb > This->data_len-This->cur ? This->data_len-This->cur : cb);

    if(!*pcbRead)
        return S_FALSE;

    memcpy(pv, This->data+This->cur, *pcbRead);
    This->cur += *pcbRead;

    return S_OK;
}

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

static HRESULT WINAPI ResProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
{
    ResProtocol *This = ResProtocol_from_IInternetProtocol(iface);

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

    /* test show that we don't have to do anything here */
    return S_OK;
}

static HRESULT WINAPI ResProtocol_UnlockRequest(IInternetProtocol *iface)
{
    ResProtocol *This = ResProtocol_from_IInternetProtocol(iface);

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

    /* test show that we don't have to do anything here */
    return S_OK;
}

static const IInternetProtocolVtbl ResProtocolVtbl = {
    ResProtocol_QueryInterface,
    ResProtocol_AddRef,
    ResProtocol_Release,
    ResProtocol_Start,
    ResProtocol_Continue,
    ResProtocol_Abort,
    ResProtocol_Terminate,
    ResProtocol_Suspend,
    ResProtocol_Resume,
    ResProtocol_Read,
    ResProtocol_Seek,
    ResProtocol_LockRequest,
    ResProtocol_UnlockRequest
};

static HRESULT WINAPI ResProtocolFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter,
        REFIID riid, void **ppv)
{
    ResProtocol *ret;
    HRESULT hres = S_OK;

    TRACE("(%p)->(%p %s %p)\n", iface, pUnkOuter, debugstr_guid(riid), ppv);

    ret = heap_alloc(sizeof(ResProtocol));
    ret->IInternetProtocol_iface.lpVtbl = &ResProtocolVtbl;
    ret->ref = 0;
    ret->data = NULL;
    ret->data_len = 0;
    ret->cur = 0;
    ret->pUnkOuter = pUnkOuter;

    if(pUnkOuter) {
        ret->ref = 1;
        if(IsEqualGUID(&IID_IUnknown, riid))
            *ppv = &ret->IInternetProtocol_iface;
        else
            hres = E_FAIL;
    }else {
        hres = IInternetProtocol_QueryInterface(&ret->IInternetProtocol_iface, riid, ppv);
    }

    if(FAILED(hres))
        heap_free(ret);

    return hres;
}

static HRESULT WINAPI ResProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
        PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
        DWORD* pcchResult, DWORD dwReserved)
{
    TRACE("%p)->(%s %d %x %p %d %p %d)\n", iface, debugstr_w(pwzUrl), ParseAction,
            dwParseFlags, pwzResult, cchResult, pcchResult, dwReserved);

    if(ParseAction == PARSE_SECURITY_URL) {
        WCHAR file_part[MAX_PATH], full_path[MAX_PATH];
        WCHAR *ptr;
        DWORD size, len;

        static const WCHAR wszFile[] = {'f','i','l','e',':','/','/'};
        static const WCHAR wszRes[] = {'r','e','s',':','/','/'};

        if(strlenW(pwzUrl) <= sizeof(wszRes)/sizeof(WCHAR) || memcmp(pwzUrl, wszRes, sizeof(wszRes)))
            return E_INVALIDARG;

        ptr = strchrW(pwzUrl + sizeof(wszRes)/sizeof(WCHAR), '/');
        if(!ptr)
            return E_INVALIDARG;

        len = ptr - (pwzUrl + sizeof(wszRes)/sizeof(WCHAR));
        if(len >= sizeof(file_part)/sizeof(WCHAR)) {
            FIXME("Too long URL\n");
            return MK_E_SYNTAX;
        }

        memcpy(file_part, pwzUrl + sizeof(wszRes)/sizeof(WCHAR), len*sizeof(WCHAR));
        file_part[len] = 0;

        len = SearchPathW(NULL, file_part, NULL, sizeof(full_path)/sizeof(WCHAR), full_path, NULL);
        if(!len) {
            HMODULE module;

            /* SearchPath does not work well with winelib files (like our test executable),
             * so we also try to load the library here */
            module = LoadLibraryExW(file_part, NULL, LOAD_LIBRARY_AS_DATAFILE);
            if(!module) {
                WARN("Could not find file %s\n", debugstr_w(file_part));
                return MK_E_SYNTAX;
            }

            len = GetModuleFileNameW(module, full_path, sizeof(full_path)/sizeof(WCHAR));
            FreeLibrary(module);
            if(!len)
                return E_FAIL;
        }

        size = sizeof(wszFile)/sizeof(WCHAR) + len + 1;
        if(pcchResult)
            *pcchResult = size;
        if(size > cchResult)
            return S_FALSE;

        memcpy(pwzResult, wszFile, sizeof(wszFile));
        memcpy(pwzResult + sizeof(wszFile)/sizeof(WCHAR), full_path, (len+1)*sizeof(WCHAR));
        return S_OK;
    }

    if(ParseAction == PARSE_DOMAIN) {
        if(!pcchResult)
            return E_POINTER;

        if(pwzUrl)
            *pcchResult = strlenW(pwzUrl)+1;
        else
            *pcchResult = 1;
        return E_FAIL;
    }

    return INET_E_DEFAULT_ACTION;
}

static HRESULT WINAPI ResProtocolInfo_QueryInfo(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
        QUERYOPTION QueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD* pcbBuf,
        DWORD dwReserved)
{
    TRACE("%p)->(%s %08x %08x %p %d %p %d)\n", iface, debugstr_w(pwzUrl), QueryOption, dwQueryFlags, pBuffer,
          cbBuffer, pcbBuf, dwReserved);

    switch(QueryOption) {
    case QUERY_USES_NETWORK:
        if(!pBuffer || cbBuffer < sizeof(DWORD))
            return E_FAIL;

        *(DWORD*)pBuffer = 0;
        if(pcbBuf)
            *pcbBuf = sizeof(DWORD);
        break;

    case QUERY_IS_SECURE:
        FIXME("QUERY_IS_SECURE not supported\n");
        return E_NOTIMPL;
    case QUERY_IS_SAFE:
        FIXME("QUERY_IS_SAFE not supported\n");
        return E_NOTIMPL;
    default:
        return INET_E_USE_DEFAULT_PROTOCOLHANDLER;
    }

    return S_OK;
}

static const IInternetProtocolInfoVtbl ResProtocolInfoVtbl = {
    InternetProtocolInfo_QueryInterface,
    InternetProtocolInfo_AddRef,
    InternetProtocolInfo_Release,
    ResProtocolInfo_ParseUrl,
    InternetProtocolInfo_CombineUrl,
    InternetProtocolInfo_CompareUrl,
    ResProtocolInfo_QueryInfo
};

static const IClassFactoryVtbl ResProtocolFactoryVtbl = {
    ClassFactory_QueryInterface,
    ClassFactory_AddRef,
    ClassFactory_Release,
    ResProtocolFactory_CreateInstance,
    ClassFactory_LockServer
};

static ProtocolFactory ResProtocolFactory = {
    { &ResProtocolInfoVtbl },
    { &ResProtocolFactoryVtbl }
};

/********************************************************************
 * JSProtocol implementation
 */

static HRESULT WINAPI JSProtocolFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter,
        REFIID riid, void **ppv)
{
    FIXME("(%p)->(%p %s %p)\n", iface, pUnkOuter, debugstr_guid(riid), ppv);
    return E_NOTIMPL;
}

static HRESULT WINAPI JSProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
        PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
        DWORD* pcchResult, DWORD dwReserved)
{
    TRACE("%p)->(%s %d %x %p %d %p %d)\n", iface, debugstr_w(pwzUrl), ParseAction,
          dwParseFlags, pwzResult, cchResult, pcchResult, dwReserved);

    switch(ParseAction) {
    case PARSE_SECURITY_URL:
        FIXME("PARSE_SECURITY_URL\n");
        return E_NOTIMPL;
    case PARSE_DOMAIN:
        FIXME("PARSE_DOMAIN\n");
        return E_NOTIMPL;
    default:
        return INET_E_DEFAULT_ACTION;
    }

    return S_OK;
}

static HRESULT WINAPI JSProtocolInfo_QueryInfo(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
        QUERYOPTION QueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD* pcbBuf,
        DWORD dwReserved)
{
    TRACE("%p)->(%s %08x %08x %p %d %p %d)\n", iface, debugstr_w(pwzUrl), QueryOption, dwQueryFlags, pBuffer,
          cbBuffer, pcbBuf, dwReserved);

    switch(QueryOption) {
    case QUERY_USES_NETWORK:
        if(!pBuffer || cbBuffer < sizeof(DWORD))
            return E_FAIL;

        *(DWORD*)pBuffer = 0;
        if(pcbBuf)
            *pcbBuf = sizeof(DWORD);
        break;

    case QUERY_IS_SECURE:
        FIXME("QUERY_IS_SECURE not supported\n");
        return E_NOTIMPL;

    default:
        return INET_E_USE_DEFAULT_PROTOCOLHANDLER;
    }

    return S_OK;
}

static const IInternetProtocolInfoVtbl JSProtocolInfoVtbl = {
    InternetProtocolInfo_QueryInterface,
    InternetProtocolInfo_AddRef,
    InternetProtocolInfo_Release,
    JSProtocolInfo_ParseUrl,
    InternetProtocolInfo_CombineUrl,
    InternetProtocolInfo_CompareUrl,
    JSProtocolInfo_QueryInfo
};

static const IClassFactoryVtbl JSProtocolFactoryVtbl = {
    ClassFactory_QueryInterface,
    ClassFactory_AddRef,
    ClassFactory_Release,
    JSProtocolFactory_CreateInstance,
    ClassFactory_LockServer
};

static ProtocolFactory JSProtocolFactory = {
    { &JSProtocolInfoVtbl },
    { &JSProtocolFactoryVtbl }
};

HRESULT ProtocolFactory_Create(REFCLSID rclsid, REFIID riid, void **ppv)
{
    ProtocolFactory *cf = NULL;

    if(IsEqualGUID(&CLSID_AboutProtocol, rclsid))
        cf = &AboutProtocolFactory;
    else if(IsEqualGUID(&CLSID_ResProtocol, rclsid))
        cf = &ResProtocolFactory;
    else if(IsEqualGUID(&CLSID_JSProtocol, rclsid))
        cf = &JSProtocolFactory;

    if(!cf) {
        FIXME("not implemented protocol %s\n", debugstr_guid(rclsid));
        return CLASS_E_CLASSNOTAVAILABLE;
    }
 
    return IInternetProtocolInfo_QueryInterface(&cf->IInternetProtocolInfo_iface, riid, ppv);
}
