/*
 * 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 const WCHAR clsid_keyname[] = {'C','L','S','I','D',0 };
static const WCHAR ips32_keyname[] = {'I','n','P','r','o','c','S','e','r','v','e','r','3','2',0};
static const WCHAR tmodel_keyname[] = {'T','h','r','e','a','d','i','n','g','M','o','d','e','l',0};
static const WCHAR 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.s1.cPins = pFilter->pins;
            rf2.u.s1.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)
    {
        char dllname[MAX_PATH];
        if (!GetModuleFileNameA(g_hInst, dllname, sizeof(dllname)))
            strcpy(dllname, "???");
        ERR("%s: no class found in %s.\n", debugstr_guid(rclsid), dllname);
        return CLASS_E_CLASSNOTAVAILABLE;
    }
    else if (!pList->m_lpfnNew)
    {
        FIXME("%s: class not implemented yet.\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;
}
