/*
 * Implementation of class factory for IE Web Browser
 *
 * Copyright 2001 John R. Sheets (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
 */

#include <string.h>
#include <stdio.h>

#include "shdocvw.h"
#include "winreg.h"
#include "advpub.h"
#include "isguids.h"

#include "winver.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);

/**********************************************************************
 * Implement the WebBrowser class factory
 *
 * (Based on implementation in ddraw/main.c)
 */

#define FACTORY(x) ((IClassFactory*) &(x)->lpClassFactoryVtbl)

typedef struct
{
    /* IUnknown fields */
    const IClassFactoryVtbl *lpClassFactoryVtbl;
    HRESULT (*cf)(LPUNKNOWN, REFIID, LPVOID *);
    LONG ref;
} IClassFactoryImpl;


/**********************************************************************
 * WBCF_QueryInterface (IUnknown)
 */
static HRESULT WINAPI WBCF_QueryInterface(LPCLASSFACTORY iface,
                                          REFIID riid, LPVOID *ppobj)
{
    TRACE("(%s %p)\n", debugstr_guid(riid), ppobj);

    if (!ppobj)
        return E_POINTER;

    if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
        *ppobj = iface;
        IClassFactory_AddRef(iface);
        return S_OK;
    }

    WARN("Not supported interface %s\n", debugstr_guid(riid));

    *ppobj = NULL;
    return E_NOINTERFACE;
}

/************************************************************************
 * WBCF_AddRef (IUnknown)
 */
static ULONG WINAPI WBCF_AddRef(LPCLASSFACTORY iface)
{
    SHDOCVW_LockModule();

    return 2; /* non-heap based object */
}

/************************************************************************
 * WBCF_Release (IUnknown)
 */
static ULONG WINAPI WBCF_Release(LPCLASSFACTORY iface)
{
    SHDOCVW_UnlockModule();

    return 1; /* non-heap based object */
}

/************************************************************************
 * WBCF_CreateInstance (IClassFactory)
 */
static HRESULT WINAPI WBCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter,
                                          REFIID riid, LPVOID *ppobj)
{
    IClassFactoryImpl *This = (IClassFactoryImpl *) iface;
    return This->cf(pOuter, riid, ppobj);
}

/************************************************************************
 * WBCF_LockServer (IClassFactory)
 */
static HRESULT WINAPI WBCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
{
    TRACE("(%d)\n", dolock);

    if (dolock)
        SHDOCVW_LockModule();
    else
        SHDOCVW_UnlockModule();
    
    return S_OK;
}

static const IClassFactoryVtbl WBCF_Vtbl =
{
    WBCF_QueryInterface,
    WBCF_AddRef,
    WBCF_Release,
    WBCF_CreateInstance,
    WBCF_LockServer
};

/*************************************************************************
 *              DllGetClassObject (SHDOCVW.@)
 */
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
{
    static IClassFactoryImpl WB1ClassFactory = {&WBCF_Vtbl, WebBrowserV1_Create};
    static IClassFactoryImpl WB2ClassFactory = {&WBCF_Vtbl, WebBrowserV2_Create};
    static IClassFactoryImpl CUHClassFactory = {&WBCF_Vtbl, CUrlHistory_Create};
    static IClassFactoryImpl ISCClassFactory = {&WBCF_Vtbl, InternetShortcut_Create};
    static IClassFactoryImpl TBLClassFactory = {&WBCF_Vtbl, TaskbarList_Create};

    TRACE("\n");

    if(IsEqualGUID(&CLSID_WebBrowser, rclsid))
        return IClassFactory_QueryInterface(FACTORY(&WB2ClassFactory), riid, ppv);

    if(IsEqualGUID(&CLSID_WebBrowser_V1, rclsid))
        return IClassFactory_QueryInterface(FACTORY(&WB1ClassFactory), riid, ppv);

    if(IsEqualGUID(&CLSID_CUrlHistory, rclsid))
        return IClassFactory_QueryInterface(FACTORY(&CUHClassFactory), riid, ppv);

    if(IsEqualGUID(&CLSID_InternetShortcut, rclsid))
        return IClassFactory_QueryInterface(FACTORY(&ISCClassFactory), riid, ppv);

    if(IsEqualGUID(&CLSID_TaskbarList, rclsid))
        return IClassFactory_QueryInterface(FACTORY(&TBLClassFactory), riid, ppv);

    /* As a last resort, figure if the CLSID belongs to a 'Shell Instance Object' */
    return SHDOCVW_GetShellInstanceObjectClassObject(rclsid, riid, ppv);
}

HRESULT register_class_object(BOOL do_reg)
{
    HRESULT hres;

    static DWORD cookie;
    static IClassFactoryImpl IEClassFactory = {&WBCF_Vtbl, InternetExplorer_Create};

    if(do_reg) {
        hres = CoRegisterClassObject(&CLSID_InternetExplorer, (IUnknown*)FACTORY(&IEClassFactory),
                                     CLSCTX_SERVER, REGCLS_MULTIPLEUSE|REGCLS_SUSPENDED, &cookie);
        if (FAILED(hres)) {
            ERR("failed to register object %08x\n", hres);
            return hres;
        }

        hres = CoResumeClassObjects();
        if(SUCCEEDED(hres))
            return hres;

        ERR("failed to resume object %08x\n", hres);
    }

    return CoRevokeClassObject(cookie);
}

static HRESULT reg_install(LPCSTR section, STRTABLEA *strtable)
{
    HRESULT (WINAPI *pRegInstall)(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable);
    HMODULE hadvpack;
    HRESULT hres;

    static const WCHAR advpackW[] = {'a','d','v','p','a','c','k','.','d','l','l',0};

    hadvpack = LoadLibraryW(advpackW);
    pRegInstall = (void *)GetProcAddress(hadvpack, "RegInstall");

    hres = pRegInstall(shdocvw_hinstance, section, strtable);

    FreeLibrary(hadvpack);
    return hres;
}

static const GUID CLSID_MicrosoftBrowserArchitecture =
    {0xa5e46e3a, 0x8849, 0x11d1, {0x9d, 0x8c, 0x00, 0xc0, 0x4f, 0xc9, 0x9d, 0x61}};
static const GUID CLSID_MruLongList =
    {0x53bd6b4e, 0x3780, 0x4693, {0xaf, 0xc3, 0x71, 0x61, 0xc2, 0xf3, 0xee, 0x9c}};

#define INF_SET_CLSID(clsid)                  \
    do                                        \
    {                                         \
        static CHAR name[] = "CLSID_" #clsid; \
                                              \
        pse[i].pszName = name;                \
        clsids[i++] = &CLSID_ ## clsid;       \
    } while (0)

static HRESULT register_server(BOOL doregister)
{
    STRTABLEA strtable;
    STRENTRYA pse[15];
    static CLSID const *clsids[15];
    unsigned int i = 0;
    HRESULT hres;

    INF_SET_CLSID(CUrlHistory);
    INF_SET_CLSID(Internet);
    INF_SET_CLSID(InternetExplorer);
    INF_SET_CLSID(InternetShortcut);
    INF_SET_CLSID(MicrosoftBrowserArchitecture);
    INF_SET_CLSID(MruLongList);
    INF_SET_CLSID(SearchAssistantOC);
    INF_SET_CLSID(ShellNameSpace);
    INF_SET_CLSID(ShellSearchAssistantOC);
    INF_SET_CLSID(ShellShellNameSpace);
    INF_SET_CLSID(ShellUIHelper);
    INF_SET_CLSID(ShellWindows);
    INF_SET_CLSID(TaskbarList);
    INF_SET_CLSID(WebBrowser);
    INF_SET_CLSID(WebBrowser_V1);

    for(i = 0; i < sizeof(pse)/sizeof(pse[0]); i++) {
        pse[i].pszValue = HeapAlloc(GetProcessHeap(), 0, 39);
        sprintf(pse[i].pszValue, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
                clsids[i]->Data1, clsids[i]->Data2, clsids[i]->Data3, clsids[i]->Data4[0],
                clsids[i]->Data4[1], clsids[i]->Data4[2], clsids[i]->Data4[3], clsids[i]->Data4[4],
                clsids[i]->Data4[5], clsids[i]->Data4[6], clsids[i]->Data4[7]);
    }

    strtable.cEntries = sizeof(pse)/sizeof(pse[0]);
    strtable.pse = pse;

    hres = reg_install(doregister ? "RegisterDll" : "UnregisterDll", &strtable);

    for(i=0; i < sizeof(pse)/sizeof(pse[0]); i++)
        HeapFree(GetProcessHeap(), 0, pse[i].pszValue);

    return hres;
}

#undef INF_SET_CLSID

/***********************************************************************
 *          DllRegisterServer (shdocvw.@)
 */
HRESULT WINAPI DllRegisterServer(void)
{
    ITypeLib *typelib;
    HRESULT hres;

    static const WCHAR shdocvwW[] = {'s','h','d','o','c','v','w','.','d','l','l',0};

    hres = register_server(TRUE);
    if(FAILED(hres))
        return hres;

    hres = LoadTypeLibEx(shdocvwW, REGKIND_REGISTER, &typelib);
    if(FAILED(hres)) {
        ERR("Could not load typelib: %08x\n", hres);
        return hres;
    }

    ITypeLib_Release(typelib);

    return hres;
}

/***********************************************************************
 *          DllUnregisterServer (shdocvw.@)
 */
HRESULT WINAPI DllUnregisterServer(void)
{
    HRESULT hres;

    hres = register_server(FALSE);
    if(FAILED(hres))
        return hres;

    return UnRegisterTypeLib(&LIBID_SHDocVw, 1, 1, LOCALE_SYSTEM_DEFAULT, SYS_WIN32);
}

static BOOL check_native_ie(void)
{
    static const WCHAR cszPath[] = {'b','r','o','w','s','e','u','i','.','d','l','l',0};
    DWORD handle,size;
    BOOL ret = TRUE;

    size = GetFileVersionInfoSizeW(cszPath,&handle);
    if (size)
    {
        LPVOID buf;
        LPWSTR lpFileDescription;
        UINT dwBytes;
        static const WCHAR cszFD[] = {'\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o','\\','0','4','0','9','0','4','e','4','\\','F','i','l','e','D','e','s','c','r','i','p','t','i','o','n',0};
        static const WCHAR cszWine[] = {'W','i','n','e',0};

        buf = HeapAlloc(GetProcessHeap(),0,size);
        GetFileVersionInfoW(cszPath,0,size,buf);

        if (VerQueryValueW(buf, cszFD, (LPVOID*)&lpFileDescription, &dwBytes) &&
            strstrW(lpFileDescription,cszWine))
                ret = FALSE;

        HeapFree(GetProcessHeap(), 0, buf);
    }

    return ret;
}

DWORD register_iexplore(BOOL doregister)
{
    HRESULT hres;
    if (check_native_ie())
    {
        TRACE("Native IE detected, not doing registration\n");
        return S_OK;
    }
    hres = reg_install(doregister ? "RegisterIE" : "UnregisterIE", NULL);
    return FAILED(hres);
}
