/*
 * DirectX DLL registration and unregistration
 *
 * Copyright (C) 2005 Rolf Kalbermatter
*
 * 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 <assert.h>

#define COBJMACROS
#define NONAMELESSSTRUCT
#define NONAMELESSUNION

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

#include "dllsetup.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(qcap);

/*
 * 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};

/*
 * Delete a key and all its subkeys
 */
HRESULT DeleteEntireSubKey(HKEY hkey, LPWSTR strSubKey)
{
    WCHAR buffer[MAX_KEY_LEN];
    DWORD dw = MAX_KEY_LEN;
    FILETIME ft;
    HKEY hk;
    LONG ret = RegOpenKeyExW(hkey, strSubKey, 0, MAXIMUM_ALLOWED, &hk);

    if (ERROR_SUCCESS == ret)
    {
        /* Keep on enumerating the first key and deleting that */
        for( ; ; )
        {
            dw = MAX_KEY_LEN;

            ret = RegEnumKeyExW(hk, 0, buffer, &dw, NULL, NULL, NULL, &ft);

            if (ERROR_SUCCESS == ret)
                DeleteEntireSubKey(hk, buffer);
            else
                break;
        }
        RegCloseKey(hk);
        RegDeleteKeyW(hkey, strSubKey);
    }
    return NOERROR;
}

/*
 * SetupRegisterClass()
 */
static HRESULT SetupRegisterClass(HKEY clsid, LPCWSTR szCLSID,
                                  LPCWSTR szDescription,
                                  LPCWSTR szFileName,
                                  LPCWSTR szServerType,
                                  LPCWSTR szThreadingModel)
{
    HKEY hkey, hsubkey;
    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);
}

/*
 * SetupRegisterFilter through IFilterMapper2
 */
static HRESULT SetupRegisterFilter2(const AMOVIESETUP_FILTER * const pSetup,
                                    IFilterMapper2 * pIFM2, BOOL bRegister)
{
    HRESULT hr;

    if (NULL == pSetup)
        return S_FALSE;

    /* unregister filter */
    hr = IFilterMapper2_UnregisterFilter(pIFM2, 0, 0, pSetup->clsID);

    if (bRegister)
    {
        REGFILTER2 rf2;
        rf2.dwVersion = 1;
        rf2.dwMerit = pSetup->dwMerit;
        rf2.u.s.cPins = pSetup->nPins;
        rf2.u.s.rgPins = pSetup->lpPin;
    
        /* register filter */
        hr = IFilterMapper2_RegisterFilter(pIFM2, pSetup->clsID,
                                           pSetup->strName, 0, 0, NULL, &rf2);
    }
    else
    {
        /* filter not found is ignored here,
           but there is no #define for 0x80070002  */
        if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
            hr = NOERROR;
    }
    return hr;
}

/*
 * SetupRegisterFilter through IFilterMapper
 */
static HRESULT SetupRegisterFilter(const AMOVIESETUP_FILTER * const pSetup,
                                   IFilterMapper * pIFM, BOOL bRegister)
{
    HRESULT hr;

    if (NULL == pSetup)
        return S_FALSE;

    /* unregister filter */
    hr = IFilterMapper_UnregisterFilter(pIFM, *pSetup->clsID);

    if (bRegister)
    {
        /* register filter */
        hr = IFilterMapper_RegisterFilter(pIFM, *pSetup->clsID,
                                          pSetup->strName, pSetup->dwMerit);
        if (SUCCEEDED(hr))
        {
            const AMOVIESETUP_PIN *lpPin = pSetup->lpPin;
            const AMOVIESETUP_MEDIATYPE *lpType;
            UINT i, j;

            for (i = 0; i < pSetup->nPins; i++, lpPin++)
            {
                hr = IFilterMapper_RegisterPin(pIFM, *(pSetup->clsID),
                                               lpPin->strName,
                                               lpPin->bRendered,
                                               lpPin->bOutput,
                                               lpPin->bZero,
                                               lpPin->bMany,
                                               *(lpPin->clsConnectsToFilter),
                                               lpPin->strConnectsToPin);

                if (SUCCEEDED(hr))
                {
                    lpType = lpPin->lpMediaType;

                    /* and each pin's media types */
                    for (j = 0; j < lpPin->nMediaTypes; j++, lpType++)
                    {
                        hr = IFilterMapper_RegisterPinType(pIFM, *(pSetup->clsID),
                                                           lpPin->strName,
                                                           *(lpType->clsMajorType),
                                                           *(lpType->clsMinorType));
                        if (FAILED(hr)) break;
                    }
                    if (FAILED(hr)) break;
                }
                if (FAILED(hr)) break;
            }
        }
    }
    else
    {
        /* filter not registered is ignored here, there is no definition for 0x80070002  */
        if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
           hr = NOERROR;
    }
    return hr;
}

/*
 * RegisterAllClasses()
 */
static HRESULT SetupRegisterAllClasses(const CFactoryTemplate * 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 = DeleteEntireSubKey(hkey, szCLSID);
        }
    }
    RegCloseKey(hkey);
    return hr;
}


/****************************************************************************
 * SetupRegisterServers
 *
 * This function is table driven using the static members of the
 * CFactoryTemplate class defined in the Dll.
 *
 * It registers the Dll as the InprocServer32 for all the classes in
 * CFactoryTemplate
 *
 ****************************************************************************/
HRESULT SetupRegisterServers(const CFactoryTemplate * pList, int num,
                             HINSTANCE hinst, BOOL bRegister)
{
    HRESULT hr = NOERROR;
    WCHAR szFileName[MAX_PATH];
    IFilterMapper2 *pIFM2 = NULL;
    IFilterMapper *pIFM = NULL;

    /* Win95 wouldn't support the Unicode version of this API!! */
    if (!GetModuleFileNameW(hinst, szFileName, MAX_PATH))
        return HRESULT_FROM_WIN32(GetLastError());

    /* first register all server classes, just to make sure */
    if (bRegister)
        hr = SetupRegisterAllClasses(pList, num, szFileName, TRUE );

    /* next, register/unregister all filters */
    if (SUCCEEDED(hr))
    {
        hr = CoInitialize(NULL);

        TRACE("Getting IFilterMapper2\r\n");
        hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
                              &IID_IFilterMapper2, (void **)&pIFM2);
        if (FAILED(hr))
        {
            TRACE("- trying IFilterMapper instead\r\n");

            hr = CoCreateInstance(&CLSID_FilterMapper, NULL, CLSCTX_INPROC_SERVER,
                                  &IID_IFilterMapper, (void **)&pIFM);
        }

        if (SUCCEEDED(hr))
        {
            int i;
            
            /* scan through array of CFactoryTemplates registering all filters */
            for (i = 0; i < num; i++, pList++)
            {
                if (NULL != pList->m_pAMovieSetup_Filter)
                {
                    if (pIFM2)
                        hr = SetupRegisterFilter2(pList->m_pAMovieSetup_Filter,
                                                  pIFM2, bRegister);
                    else
                        hr = SetupRegisterFilter(pList->m_pAMovieSetup_Filter,
                                                 pIFM, bRegister);
                }

                /* check final error for this pass and break loop if we failed */
                if (FAILED(hr))
                    break;
            }

            /* release interface */
            if (pIFM2)
                IFilterMapper2_Release(pIFM2);
            else
                IFilterMapper_Release(pIFM);
        }

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

    /* if unregistering, unregister all OLE servers */
    if (SUCCEEDED(hr) && !bRegister)
        hr = SetupRegisterAllClasses(pList, num, 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 intialize function for any class in CFactoryTemplate with
 * one defined.
 *
 ****************************************************************************/
void SetupInitializeServers(const CFactoryTemplate * 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);
    }
}
