/*
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 "docobj.h"

#include "mshtml.h"
#include "mshtmhst.h"

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

#include "mshtml_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(mshtml);

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

#define PROTOCOLINFO(x) ((IInternetProtocolInfo*) &(x)->lpInternetProtocolInfoVtbl)
#define CLASSFACTORY(x) ((IClassFactory*)         &(x)->lpClassFactoryVtbl)

typedef struct {
    const IInternetProtocolInfoVtbl *lpInternetProtocolInfoVtbl;
    const IClassFactoryVtbl         *lpClassFactoryVtbl;
} ProtocolFactory;

#define PROTOCOLINFO_THIS(iface) DEFINE_THIS(ProtocolFactory, InternetProtocolInfo, iface)

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

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

    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)
{
    ProtocolFactory *This = PROTOCOLINFO_THIS(iface);
    TRACE("(%p)\n", This);
    LOCK_MODULE();
    return 2;
}

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

#undef PROTOCOLINFO_THIS

#define CLASSFACTORY_THIS(iface) DEFINE_THIS(ProtocolFactory, ClassFactory, iface)

static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
{
    ProtocolFactory *This = CLASSFACTORY_THIS(iface);
    return IInternetProtocolInfo_QueryInterface(PROTOCOLINFO(This), riid, ppv);
}

static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
{
    ProtocolFactory *This = CLASSFACTORY_THIS(iface);
    return IInternetProtocolInfo_AddRef(PROTOCOLINFO(This));
}

static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
{
    ProtocolFactory *This = CLASSFACTORY_THIS(iface);
    return IInternetProtocolInfo_Release(PROTOCOLINFO(This));
}

static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
{
    ProtocolFactory *This = CLASSFACTORY_THIS(iface);

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

    if(dolock)
        LOCK_MODULE();
    else
        UNLOCK_MODULE();

    return S_OK;
}

#undef CLASSFACTORY_THIS

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

typedef struct {
    const IInternetProtocolVtbl *lpInternetProtocolVtbl;

    LONG ref;

    BYTE *data;
    ULONG data_len;
    ULONG cur;
} AboutProtocol;

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

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
        *ppv = iface;
    }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
        TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", iface, ppv);
        *ppv = iface;
    }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
        TRACE("(%p)->(IID_IInternetProtocol %p)\n", iface, ppv);
        *ppv = 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*)iface;
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p) ref=%ld\n", iface, ref);
    return ref;
}

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

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

    if(!ref) {
        HeapFree(GetProcessHeap(), 0, This->data);
        HeapFree(GetProcessHeap(), 0, This);
        UNLOCK_MODULE();
    }

    return ref;
}

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

    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',':'};

    /* 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 %08lx %ld)\n", This, debugstr_w(szUrl), pOIProtSink,
            pOIBindInfo, grfPI, dwReserved);

    memset(&bindinfo, 0, sizeof(bindinfo));
    bindinfo.cbSize = sizeof(BINDINFO);
    IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo);

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

    This->data_len = sizeof(html_begin)+sizeof(html_end)-sizeof(WCHAR) 
        + (text ? strlenW(text)*sizeof(WCHAR) : 0);
    This->data = HeapAlloc(GetProcessHeap(), 0, This->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_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*)iface;
    FIXME("(%p)->(%p)\n", This, pProtocolData);
    return E_NOTIMPL;
}

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

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

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

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

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

    TRACE("(%p)->(%p %lu %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, *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*)iface;
    FIXME("(%p)->(%ld %ld %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
    return E_NOTIMPL;
}

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

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

    return S_OK;
}

static HRESULT WINAPI AboutProtocol_UnlockRequest(IInternetProtocol *iface)
{
    AboutProtocol *This = (AboutProtocol*)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;

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

    ret = HeapAlloc(GetProcessHeap(), 0, sizeof(AboutProtocol));
    ret->lpInternetProtocolVtbl = &AboutProtocolVtbl;
    ret->ref = 0;

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

    hres = IUnknown_QueryInterface((IUnknown*)ret, riid, ppv);

    if(SUCCEEDED(hres))
        LOCK_MODULE();
    else
        HeapFree(GetProcessHeap(), 0, ret);

    return hres;
}

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

static HRESULT WINAPI AboutProtocolInfo_CombineUrl(IInternetProtocolInfo *iface, LPCWSTR pwzBaseUrl,
        LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags, LPWSTR pwzResult, DWORD cchResult,
        DWORD* pcchResult, DWORD dwReserved)
{
    FIXME("%p)->(%s %s %08lx %p %ld %p %ld)\n", iface, debugstr_w(pwzBaseUrl), debugstr_w(pwzRelativeUrl),
            dwCombineFlags, pwzResult, cchResult, pcchResult, dwReserved);
    return E_NOTIMPL;
}

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

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

static const IInternetProtocolInfoVtbl AboutProtocolInfoVtbl = {
    InternetProtocolInfo_QueryInterface,
    InternetProtocolInfo_AddRef,
    InternetProtocolInfo_Release,
    AboutProtocolInfo_ParseUrl,
    AboutProtocolInfo_CombineUrl,
    AboutProtocolInfo_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 {
    const IInternetProtocolVtbl *lpInternetProtocolVtbl;
    LONG ref;

    BYTE *data;
    ULONG data_len;
    ULONG cur;
} ResProtocol;

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

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
        *ppv = iface;
    }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
        TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", iface, ppv);
        *ppv = iface;
    }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
        TRACE("(%p)->(IID_IInternetProtocol %p)\n", iface, ppv);
        *ppv = 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*)iface;
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p) ref=%ld\n", iface, ref);
    return ref;
}

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

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

    if(!ref) {
        HeapFree(GetProcessHeap(), 0, This->data);
        HeapFree(GetProcessHeap(), 0, This);
        UNLOCK_MODULE();
    }

    return ref;
}

static HRESULT WINAPI ResProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
        IInternetProtocolSink* pOIProtSink, IInternetBindInfo* pOIBindInfo,
        DWORD grfPI, DWORD dwReserved)
{
    ResProtocol *This = (ResProtocol*)iface;
    DWORD grfBINDF = 0;
    BINDINFO bindinfo;
    int len;
    WCHAR dll[MAX_PATH];
    LPCWSTR url_dll, url_file;
    HMODULE hdll;
    HRSRC src;

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

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

    memset(&bindinfo, 0, sizeof(bindinfo));
    bindinfo.cbSize = sizeof(BINDINFO);
    IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo);

    /* FIXME:
     * Implement MIME type checking
     * Use CoInternetParseUrl (not implemented yet)
     */

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

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

    memcpy(dll, url_dll, (url_file-url_dll)*sizeof(WCHAR));
    dll[url_file-url_dll] = 0;

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

    src = FindResourceW(hdll, ++url_file, (LPCWSTR)RT_HTML);
    if(!src) {
        WARN("Could not find resource: %s\n", debugstr_w(url_file));
        IInternetProtocolSink_ReportResult(pOIProtSink, HRESULT_FROM_WIN32(GetLastError()), 0, NULL);
        return HRESULT_FROM_WIN32(GetLastError());
    }

    if(This->data) {
        WARN("data already loaded\n");
        HeapFree(GetProcessHeap(), 0, This->data);
    }

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

    FreeLibrary(hdll);

    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*)iface;
    FIXME("(%p)->(%p)\n", This, pProtocolData);
    return E_NOTIMPL;
}

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

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

    TRACE("(%p)->(%08lx)\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*)iface;
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

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

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

    TRACE("(%p)->(%p %lu %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, *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*)iface;
    FIXME("(%p)->(%ld %ld %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
    return E_NOTIMPL;
}

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

    TRACE("(%p)->(%ld)\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*)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;

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

    ret = HeapAlloc(GetProcessHeap(), 0, sizeof(ResProtocol));
    ret->lpInternetProtocolVtbl = &ResProtocolVtbl;
    ret->ref = 0;
    ret->data = NULL;
    ret->data_len = 0;
    ret->cur = 0;

    hres = IUnknown_QueryInterface((IUnknown*)ret, riid, ppv);

    if(SUCCEEDED(hres))
        LOCK_MODULE();
    else
        HeapFree(GetProcessHeap(), 0, ret);

    return hres;
}

static HRESULT WINAPI ResProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
        PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
        DWORD* pcchResult, DWORD dwReserved)
{
    FIXME("%p)->(%s %08x %08lx %p %ld %p %ld)\n", iface, debugstr_w(pwzUrl), ParseAction,
            dwParseFlags, pwzResult, cchResult, pcchResult, dwReserved);
    return E_NOTIMPL;
}

static HRESULT WINAPI ResProtocolInfo_CombineUrl(IInternetProtocolInfo *iface, LPCWSTR pwzBaseUrl,
        LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags, LPWSTR pwzResult, DWORD cchResult,
        DWORD* pcchResult, DWORD dwReserved)
{
    FIXME("%p)->(%s %s %08lx %p %ld %p %ld)\n", iface, debugstr_w(pwzBaseUrl), debugstr_w(pwzRelativeUrl),
            dwCombineFlags, pwzResult, cchResult, pcchResult, dwReserved);
    return E_NOTIMPL;
}

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

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

static const IInternetProtocolInfoVtbl ResProtocolInfoVtbl = {
    InternetProtocolInfo_QueryInterface,
    InternetProtocolInfo_AddRef,
    InternetProtocolInfo_Release,
    ResProtocolInfo_ParseUrl,
    ResProtocolInfo_CombineUrl,
    ResProtocolInfo_CompareUrl,
    ResProtocolInfo_QueryInfo
};

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

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

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;

    if(!cf) {
        FIXME("not implemented protocol %s\n", debugstr_guid(rclsid));
        return CLASS_E_CLASSNOTAVAILABLE;
    }
 
    return IUnknown_QueryInterface((IUnknown*)cf, riid, ppv);
}
