/*
 * Strmbase DLL functions
 *
 * Copyright (C) 2005 Rolf Kalbermatter
 * Copyright (C) 2010 Aric Stewart, 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 "config.h"

#include <stdarg.h>
#include <assert.h>

#define COBJMACROS
#define NONAMELESSSTRUCT
#define NONAMELESSUNION

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winerror.h"
#include "winreg.h"
#include "objbase.h"
#include "uuids.h"
#include "strmif.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(strmbase);

extern const int g_cTemplates;
extern const FactoryTemplate g_Templates[];

static HINSTANCE g_hInst = NULL;
static LONG server_locks = 0;

/*
 * defines and constants
 */
#define MAX_KEY_LEN  260

static WCHAR const clsid_keyname[6] =
{'C','L','S','I','D',0 };
static WCHAR const ips32_keyname[15] =
{'I','n','P','r','o','c','S','e','r','v','e','r','3','2',0};
static WCHAR const tmodel_keyname[15] =
{'T','h','r','e','a','d','i','n','g','M','o','d','e','l',0};
static WCHAR const tmodel_both[] =
{'B','o','t','h',0};

/*
 * SetupRegisterClass()
 */
static HRESULT SetupRegisterClass(HKEY clsid, LPCWSTR szCLSID,
                                  LPCWSTR szDescription,
                                  LPCWSTR szFileName,
                                  LPCWSTR szServerType,
                                  LPCWSTR szThreadingModel)
{
    HKEY hkey, hsubkey = NULL;
    LONG ret = RegCreateKeyW(clsid, szCLSID, &hkey);
    if (ERROR_SUCCESS != ret)
        return HRESULT_FROM_WIN32(ret);

    /* set description string */
    ret = RegSetValueW(hkey, NULL, REG_SZ, szDescription,
                       sizeof(WCHAR) * (lstrlenW(szDescription) + 1));
    if (ERROR_SUCCESS != ret)
        goto err_out;

    /* create CLSID\\{"CLSID"}\\"ServerType" key, using key to CLSID\\{"CLSID"}
       passed back by last call to RegCreateKeyW(). */
    ret = RegCreateKeyW(hkey,  szServerType, &hsubkey);
    if (ERROR_SUCCESS != ret)
        goto err_out;

    /* set server path */
    ret = RegSetValueW(hsubkey, NULL, REG_SZ, szFileName,
                       sizeof(WCHAR) * (lstrlenW(szFileName) + 1));
    if (ERROR_SUCCESS != ret)
        goto err_out;

    /* set threading model */
    ret = RegSetValueExW(hsubkey, tmodel_keyname, 0L, REG_SZ,
                         (const BYTE*)szThreadingModel,
                         sizeof(WCHAR) * (lstrlenW(szThreadingModel) + 1));
err_out:
    if (hsubkey)
        RegCloseKey(hsubkey);
    RegCloseKey(hkey);
    return HRESULT_FROM_WIN32(ret);
}

/*
 * RegisterAllClasses()
 */
static HRESULT SetupRegisterAllClasses(const FactoryTemplate * pList, int num,
                                       LPCWSTR szFileName, BOOL bRegister)
{
    HRESULT hr = NOERROR;
    HKEY hkey;
    OLECHAR szCLSID[CHARS_IN_GUID];
    LONG i, ret = RegCreateKeyW(HKEY_CLASSES_ROOT, clsid_keyname, &hkey);
    if (ERROR_SUCCESS != ret)
        return HRESULT_FROM_WIN32(ret);

    for (i = 0; i < num; i++, pList++)
    {
        /* (un)register CLSID and InprocServer32 */
        hr = StringFromGUID2(pList->m_ClsID, szCLSID, CHARS_IN_GUID);
        if (SUCCEEDED(hr))
        {
            if (bRegister )
                hr = SetupRegisterClass(hkey, szCLSID,
                                        pList->m_Name, szFileName,
                                        ips32_keyname, tmodel_both);
            else
                hr = RegDeleteTreeW(hkey, szCLSID);
        }
    }
    RegCloseKey(hkey);
    return hr;
}

HRESULT WINAPI AMovieSetupRegisterFilter2(const AMOVIESETUP_FILTER *pFilter, IFilterMapper2  *pIFM2, BOOL  bRegister)
{
    if (!pFilter)
        return S_OK;

    if (bRegister)
    {
        {
            REGFILTER2 rf2;
            rf2.dwVersion = 1;
            rf2.dwMerit = pFilter->merit;
            rf2.u.s.cPins = pFilter->pins;
            rf2.u.s.rgPins = pFilter->pPin;

            return IFilterMapper2_RegisterFilter(pIFM2, pFilter->clsid, pFilter->name, NULL, &CLSID_LegacyAmFilterCategory, NULL, &rf2);
        }
    }
    else
       return IFilterMapper2_UnregisterFilter(pIFM2, &CLSID_LegacyAmFilterCategory, NULL, pFilter->clsid);
}

HRESULT WINAPI AMovieDllRegisterServer2(BOOL bRegister)
{
    HRESULT hr;
    int i;
    IFilterMapper2 *pIFM2 = NULL;
    WCHAR szFileName[MAX_PATH];

    if (!GetModuleFileNameW(g_hInst, szFileName, MAX_PATH))
    {
        ERR("Failed to get module file name for registration\n");
        return E_FAIL;
    }

    if (bRegister)
        hr = SetupRegisterAllClasses(g_Templates, g_cTemplates, szFileName, TRUE );

    hr = CoInitialize(NULL);

    TRACE("Getting IFilterMapper2\r\n");
    hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
                          &IID_IFilterMapper2, (void **)&pIFM2);

    for (i = 0; SUCCEEDED(hr) && i < g_cTemplates; i++)
        hr = AMovieSetupRegisterFilter2(g_Templates[i].m_pAMovieSetup_Filter, pIFM2, bRegister);

    /* release interface */
    if (pIFM2)
        IFilterMapper2_Release(pIFM2);

    /* and clear up */
    CoFreeUnusedLibraries();
    CoUninitialize();

    /* if unregistering, unregister all OLE servers */
    if (SUCCEEDED(hr) && !bRegister)
        hr = SetupRegisterAllClasses(g_Templates, g_cTemplates, szFileName, FALSE);

    return hr;
}

/****************************************************************************
 * SetupInitializeServers
 *
 * This function is table driven using the static members of the
 * CFactoryTemplate class defined in the Dll.
 *
 * It calls the initialize function for any class in CFactoryTemplate with
 * one defined.
 *
 ****************************************************************************/
static void SetupInitializeServers(const FactoryTemplate * pList, int num,
                            BOOL bLoading)
{
    int i;

    for (i = 0; i < num; i++, pList++)
    {
        if (pList->m_lpfnInit)
            pList->m_lpfnInit(bLoading, pList->m_ClsID);
    }
}

BOOL WINAPI STRMBASE_DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            g_hInst = hInstDLL;
            DisableThreadLibraryCalls(hInstDLL);
            SetupInitializeServers(g_Templates, g_cTemplates, TRUE);
            break;
        case DLL_PROCESS_DETACH:
            SetupInitializeServers(g_Templates, g_cTemplates, FALSE);
            break;
    }
    return TRUE;
}

/******************************************************************************
 * DLL ClassFactory
 */
typedef struct {
    IClassFactory ITF_IClassFactory;

    LONG ref;
    LPFNNewCOMObject pfnCreateInstance;
} IClassFactoryImpl;

static HRESULT WINAPI
DSCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj)
{
    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;

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

    WARN("(%p)->(%s,%p), not found\n", This, debugstr_guid(riid), ppobj);
    return E_NOINTERFACE;
}

static ULONG WINAPI DSCF_AddRef(LPCLASSFACTORY iface)
{
    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI DSCF_Release(LPCLASSFACTORY iface)
{
    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;

    ULONG ref = InterlockedDecrement(&This->ref);

    if (ref == 0)
        HeapFree(GetProcessHeap(), 0, This);

    return ref;
}

static HRESULT WINAPI DSCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter,
                                          REFIID riid, LPVOID *ppobj)
{
    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
    HRESULT hres = ERROR_SUCCESS;
    LPUNKNOWN punk;

    TRACE("(%p)->(%p,%s,%p)\n", This, pOuter, debugstr_guid(riid), ppobj);

    if (!ppobj)
        return E_POINTER;

    /* Enforce the normal OLE rules regarding interfaces and delegation */
    if (pOuter && !IsEqualGUID(riid, &IID_IUnknown))
        return E_NOINTERFACE;

    *ppobj = NULL;
    punk = This->pfnCreateInstance(pOuter, &hres);
    if (!punk)
    {
        /* No object created, update error if it isn't done already and return */
        if (SUCCEEDED(hres))
            hres = E_OUTOFMEMORY;
    return hres;
    }

    if (SUCCEEDED(hres))
    {
        hres = IUnknown_QueryInterface(punk, riid, ppobj);
    }
    /* Releasing the object. If everything was successful, QueryInterface
       should have incremented the refcount once more, otherwise this will
       purge the object. */
    IUnknown_Release(punk);
    return hres;
}

static HRESULT WINAPI DSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
{
    IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
    TRACE("(%p)->(%d)\n",This, dolock);

    if (dolock)
        InterlockedIncrement(&server_locks);
    else
        InterlockedDecrement(&server_locks);
    return S_OK;
}

static const IClassFactoryVtbl DSCF_Vtbl =
{
    DSCF_QueryInterface,
    DSCF_AddRef,
    DSCF_Release,
    DSCF_CreateInstance,
    DSCF_LockServer
};

/***********************************************************************
 *    DllGetClassObject
 */
HRESULT WINAPI STRMBASE_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
    const FactoryTemplate *pList = g_Templates;
    IClassFactoryImpl *factory;
    int i;

    TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);

    if (!ppv)
        return E_POINTER;

    *ppv = NULL;

    if (!IsEqualGUID(&IID_IClassFactory, riid) &&
        !IsEqualGUID(&IID_IUnknown, riid))
        return E_NOINTERFACE;

    for (i = 0; i < g_cTemplates; i++, pList++)
    {
        if (IsEqualGUID(pList->m_ClsID, rclsid))
            break;
    }

    if (i == g_cTemplates)
    {
        FIXME("%s: no class found.\n", debugstr_guid(rclsid));
        return CLASS_E_CLASSNOTAVAILABLE;
    }

    factory = HeapAlloc(GetProcessHeap(), 0, sizeof(IClassFactoryImpl));
    if (!factory)
        return E_OUTOFMEMORY;

    factory->ITF_IClassFactory.lpVtbl = &DSCF_Vtbl;
    factory->ref = 1;

    factory->pfnCreateInstance = pList->m_lpfnNew;

    *ppv = &(factory->ITF_IClassFactory);
    return S_OK;
}

/***********************************************************************
 *    DllCanUnloadNow
 */
HRESULT WINAPI STRMBASE_DllCanUnloadNow(void)
{
    TRACE("\n");

    if (server_locks == 0)
        return S_OK;
    return S_FALSE;
}
