/*
 *	exported dll functions for devenum.dll
 *
 * Copyright (C) 2002 John K. Hohm
 * Copyright (C) 2002 Robert Shearman
 *
 * 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 "devenum_private.h"
#include "wine/debug.h"
#include "winreg.h"

WINE_DEFAULT_DEBUG_CHANNEL(devenum);

LONG dll_refs;
HINSTANCE DEVENUM_hInstance;

typedef struct
{
    REFCLSID clsid;
    LPCWSTR friendly_name;
    BOOL instance;
} register_info;

static HRESULT register_clsids(int count, const register_info * pRegInfo, LPCWSTR pszThreadingModel);
static void DEVENUM_RegisterQuartz(void);

/***********************************************************************
 *		Global string constant definitions
 */
const WCHAR clsid_keyname[6] = { 'C', 'L', 'S', 'I', 'D', 0 };

/***********************************************************************
 *		DllEntryPoint
 */
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
{
    TRACE("%p 0x%x %p\n", hinstDLL, fdwReason, fImpLoad);

    switch(fdwReason) {
    case DLL_PROCESS_ATTACH:
        DEVENUM_hInstance = hinstDLL;
        DisableThreadLibraryCalls(hinstDLL);
	break;

    case DLL_PROCESS_DETACH:
        DEVENUM_hInstance = 0;
	break;
    }
    return TRUE;
}

/***********************************************************************
 *		DllGetClassObject (DEVENUM.@)
 */
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
{
    TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);

    *ppv = NULL;

    /* FIXME: we should really have two class factories.
     * Oh well - works just fine as it is */
    if (IsEqualGUID(rclsid, &CLSID_SystemDeviceEnum) ||
        IsEqualGUID(rclsid, &CLSID_CDeviceMoniker))
        return IClassFactory_QueryInterface((IClassFactory*)&DEVENUM_ClassFactory, iid, ppv);

    FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
    return CLASS_E_CLASSNOTAVAILABLE;
}

/***********************************************************************
 *		DllCanUnloadNow (DEVENUM.@)
 */
HRESULT WINAPI DllCanUnloadNow(void)
{
    return dll_refs != 0 ? S_FALSE : S_OK;
}

/***********************************************************************
 *		DllRegisterServer (DEVENUM.@)
 */
HRESULT WINAPI DllRegisterServer(void)
{
    HRESULT res;
    HKEY hkeyClsid = NULL;
    HKEY hkey1 = NULL;
    HKEY hkey2 = NULL;
    LPOLESTR pszClsidDevMon = NULL;
    IFilterMapper2 * pMapper = NULL;
    LPVOID mapvptr;
    static const WCHAR threadingModel[] = {'B','o','t','h',0};
    static const WCHAR sysdevenum[] = {'S','y','s','t','e','m',' ','D','e','v','i','c','e',' ','E','n','u','m',0};
    static const WCHAR devmon[] = {'D','e','v','i','c','e','M','o','n','i','k','e','r',0};
    static const WCHAR acmcat[] = {'A','C','M',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0};
    static const WCHAR vidcat[] = {'I','C','M',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0};
    static const WCHAR filtcat[] = {'A','c','t','i','v','e','M','o','v','i','e',' ','F','i','l','t','e','r',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0};
    static const WCHAR vfwcat[] = {'V','F','W',' ','C','a','p','t','u','r','e',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0};
    static const WCHAR wavein[] = {'W','a','v','e','I','n',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r', 0};
    static const WCHAR waveout[] = {'W','a','v','e','O','u','t',' ','a','n','d',' ','D','S','o','u','n','d',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0};
    static const WCHAR midiout[] = {'M','i','d','i','O','u','t',' ','C','l','a','s','s',' ','M','a','n','a','g','e','r',0};
    static const WCHAR amcat[] = {'A','c','t','i','v','e','M','o','v','i','e',' ','F','i','l','t','e','r',' ','C','a','t','e','g','o','r','i','e','s',0};
    static const WCHAR device[] = {'d','e','v','i','c','e',0};
    static const WCHAR device_1[] = {'d','e','v','i','c','e','.','1',0};
    static const register_info ri[] =
    {
        {&CLSID_SystemDeviceEnum, sysdevenum, FALSE},
	{&CLSID_CDeviceMoniker, devmon, FALSE},
	{&CLSID_AudioCompressorCategory, acmcat, TRUE},
	{&CLSID_VideoCompressorCategory, vidcat, TRUE},
	{&CLSID_LegacyAmFilterCategory, filtcat, TRUE},
	{&CLSID_VideoInputDeviceCategory, vfwcat, FALSE},
	{&CLSID_AudioInputDeviceCategory, wavein, FALSE},
	{&CLSID_AudioRendererCategory, waveout, FALSE},
	{&CLSID_MidiRendererCategory, midiout, FALSE},
	{&CLSID_ActiveMovieCategories, amcat, TRUE}
    };

    TRACE("\n");

    res = register_clsids(sizeof(ri) / sizeof(register_info), ri, threadingModel);

    /* Quartz is needed for IFilterMapper2 */
    DEVENUM_RegisterQuartz();

/*** ActiveMovieFilter Categories ***/

    CoInitialize(NULL);
    
    res = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC,
                           &IID_IFilterMapper2,  &mapvptr);
    if (SUCCEEDED(res))
    {
        static const WCHAR friendlyvidcap[] = {'V','i','d','e','o',' ','C','a','p','t','u','r','e',' ','S','o','u','r','c','e','s',0};
        static const WCHAR friendlydshow[] = {'D','i','r','e','c','t','S','h','o','w',' ','F','i','l','t','e','r','s',0};
        static const WCHAR friendlyvidcomp[] = {'V','i','d','e','o',' ','C','o','m','p','r','e','s','s','o','r','s',0};
        static const WCHAR friendlyaudcap[] = {'A','u','d','i','o',' ','C','a','p','t','u','r','e',' ','S','o','u','r','c','e','s',0};
        static const WCHAR friendlyaudcomp[] = {'A','u','d','i','o',' ','C','o','m','p','r','e','s','s','o','r','s',0};
        static const WCHAR friendlyaudrend[] = {'A','u','d','i','o',' ','R','e','n','d','e','r','e','r','s',0};
        static const WCHAR friendlymidirend[] = {'M','i','d','i',' ','R','e','n','d','e','r','e','r','s',0};
        static const WCHAR friendlyextrend[] = {'E','x','t','e','r','n','a','l',' ','R','e','n','d','e','r','e','r','s',0};
        static const WCHAR friendlydevctrl[] = {'D','e','v','i','c','e',' ','C','o','n','t','r','o','l',' ','F','i','l','t','e','r','s',0};

        pMapper = mapvptr;

        IFilterMapper2_CreateCategory(pMapper, &CLSID_VideoInputDeviceCategory, MERIT_DO_NOT_USE, friendlyvidcap);
        IFilterMapper2_CreateCategory(pMapper, &CLSID_LegacyAmFilterCategory, MERIT_NORMAL, friendlydshow);
        IFilterMapper2_CreateCategory(pMapper, &CLSID_VideoCompressorCategory, MERIT_DO_NOT_USE, friendlyvidcomp);
        IFilterMapper2_CreateCategory(pMapper, &CLSID_AudioInputDeviceCategory, MERIT_DO_NOT_USE, friendlyaudcap);
        IFilterMapper2_CreateCategory(pMapper, &CLSID_AudioCompressorCategory, MERIT_DO_NOT_USE, friendlyaudcomp);
        IFilterMapper2_CreateCategory(pMapper, &CLSID_AudioRendererCategory, MERIT_NORMAL, friendlyaudrend);
        IFilterMapper2_CreateCategory(pMapper, &CLSID_MidiRendererCategory, MERIT_NORMAL, friendlymidirend);
        IFilterMapper2_CreateCategory(pMapper, &CLSID_TransmitCategory, MERIT_DO_NOT_USE, friendlyextrend);
        IFilterMapper2_CreateCategory(pMapper, &CLSID_DeviceControlCategory, MERIT_DO_NOT_USE, friendlydevctrl);

        IFilterMapper2_Release(pMapper);
    }

/*** CDeviceMoniker ***/
    if (SUCCEEDED(res))
    {
	res = StringFromCLSID(&CLSID_CDeviceMoniker, &pszClsidDevMon);
    }
    if (SUCCEEDED(res))
    {
        res = RegOpenKeyW(HKEY_CLASSES_ROOT, clsid_keyname, &hkeyClsid)
	      == ERROR_SUCCESS ? S_OK : E_FAIL;
    }
    if (SUCCEEDED(res))
    {
        res = RegOpenKeyW(hkeyClsid, pszClsidDevMon, &hkey1)
	       == ERROR_SUCCESS ? S_OK : E_FAIL;
    }
    if (SUCCEEDED(res))
    {
        static const WCHAR wszProgID[] = {'P','r','o','g','I','D',0};
        res = RegCreateKeyW(hkey1, wszProgID, &hkey2)
	      == ERROR_SUCCESS ? S_OK : E_FAIL;
    }
    if (SUCCEEDED(res))
    {
        res = RegSetValueW(hkey2, NULL, REG_SZ, device_1, (lstrlenW(device_1) + 1) * sizeof(WCHAR))
	      == ERROR_SUCCESS ? S_OK : E_FAIL;
    }

    if (hkey2)
    {
        RegCloseKey(hkey2);
        hkey2 = NULL;
    }

    if (SUCCEEDED(res))
    {
        static const WCHAR wszVProgID[] = {'V','e','r','s','i','o','n','I','n','d','e','p','e','d','e','n','t','P','r','o','g','I','D',0};
	res = RegCreateKeyW(hkey1, wszVProgID, &hkey2)
	      == ERROR_SUCCESS ? S_OK : E_FAIL;
    }
    if (SUCCEEDED(res))
    {
        res = RegSetValueW(hkey2, NULL, REG_SZ, device, (lstrlenW(device) + 1) * sizeof(WCHAR))
	      == ERROR_SUCCESS ? S_OK : E_FAIL;
    }

    if (hkey2)
    {
        RegCloseKey(hkey2);
        hkey2 = NULL;
    }

    if (hkey1)
    {
        RegCloseKey(hkey1);
        hkey1 = NULL;
    }

    if (SUCCEEDED(res))
    {
        res = RegCreateKeyW(HKEY_CLASSES_ROOT, device, &hkey1)
	      == ERROR_SUCCESS ? S_OK : E_FAIL;
    }
    if (SUCCEEDED(res))
    {
        res = RegCreateKeyW(hkey1, clsid_keyname, &hkey2)
	      == ERROR_SUCCESS ? S_OK : E_FAIL;
    }
    if (SUCCEEDED(res))
    {
        res = RegSetValueW(hkey2, NULL, REG_SZ, pszClsidDevMon, (lstrlenW(pszClsidDevMon) + 1) * sizeof(WCHAR))
	      == ERROR_SUCCESS ? S_OK : E_FAIL;
    }
    if (hkey2)
    {
        RegCloseKey(hkey2);
        hkey2 = NULL;
    }

    if (hkey1)
    {
        RegCloseKey(hkey1);
        hkey1 = NULL;
    }

    if (SUCCEEDED(res))
    {
        res = RegCreateKeyW(HKEY_CLASSES_ROOT, device_1, &hkey1)
	      == ERROR_SUCCESS ? S_OK : E_FAIL;
    }
    if (SUCCEEDED(res))
    {
        res = RegCreateKeyW(hkey1, clsid_keyname, &hkey2)
	      == ERROR_SUCCESS ? S_OK : E_FAIL;
    }
    if (SUCCEEDED(res))
    {
        res = RegSetValueW(hkey2, NULL, REG_SZ, pszClsidDevMon, (lstrlenW(pszClsidDevMon) + 1) * sizeof(WCHAR))
	      == ERROR_SUCCESS ? S_OK : E_FAIL;
    }

    if (hkey2)
        RegCloseKey(hkey2);

    if (hkey1)
        RegCloseKey(hkey1);

    if (hkeyClsid)
        RegCloseKey(hkeyClsid);

    CoTaskMemFree(pszClsidDevMon);
    CoUninitialize();

    return res;
}

/***********************************************************************
 *		DllUnregisterServer (DEVENUM.@)
 */
HRESULT WINAPI DllUnregisterServer(void)
{
	FIXME("stub!\n");
	return E_FAIL;
}

static HRESULT register_clsids(int count, const register_info * pRegInfo, LPCWSTR pszThreadingModel)
{
    HRESULT res = S_OK;
    LPOLESTR clsidString = NULL;
    HKEY hkeyClsid;
    HKEY hkeySub;
    HKEY hkeyInproc32;
    HKEY hkeyInstance = NULL;
    int i;
    static const WCHAR wcszInproc32[] = {'I','n','p','r','o','c','S','e','r','v','e','r','3','2',0};
    static const WCHAR wcszThreadingModel[] = {'T','h','r','e','a','d','i','n','g','M','o','d','e','l',0};
    static const WCHAR dll_module[] = {'d','e','v','e','n','u','m','.','d','l','l',0};

    res = RegOpenKeyW(HKEY_CLASSES_ROOT, clsid_keyname, &hkeyClsid)
          == ERROR_SUCCESS ? S_OK : E_FAIL;

    for (i = 0; i < count; i++)
    {
	hkeySub = 0;
        if (SUCCEEDED(res))
	{
	    res = StringFromCLSID(pRegInfo[i].clsid, &clsidString);
	}
	if (SUCCEEDED(res))
	{
	    res = RegCreateKeyW(hkeyClsid, clsidString, &hkeySub)
	          == ERROR_SUCCESS ? S_OK : E_FAIL;
	}
	if (pRegInfo[i].instance && SUCCEEDED(res))
	{
	    res = RegCreateKeyW(hkeySub, wszInstanceKeyName, &hkeyInstance)
	          == ERROR_SUCCESS ? S_OK : E_FAIL;
            RegCloseKey(hkeyInstance);
	}
	if (SUCCEEDED(res))
	{
	    RegSetValueW(hkeySub,
	                 NULL,
		         REG_SZ,
	                 pRegInfo->friendly_name ? pRegInfo[i].friendly_name : clsidString,
		         (lstrlenW(pRegInfo[i].friendly_name ? pRegInfo->friendly_name : clsidString) + 1) * sizeof(WCHAR));
	    res = RegCreateKeyW(hkeySub, wcszInproc32, &hkeyInproc32)
	          == ERROR_SUCCESS ? S_OK : E_FAIL;
	}
	if (SUCCEEDED(res))
	{
	    RegSetValueW(hkeyInproc32,
	                 NULL,
	                 REG_SZ,
			 dll_module,
			 (lstrlenW(dll_module) + 1) * sizeof(WCHAR));
	    RegSetValueExW(hkeyInproc32,
	                   wcszThreadingModel,
			   0,
			   REG_SZ,
			   (LPCVOID)pszThreadingModel,
			   (lstrlenW(pszThreadingModel) + 1) * sizeof(WCHAR));
            RegCloseKey(hkeyInproc32);
        }
        if (hkeySub) RegCloseKey(hkeySub);
	CoTaskMemFree(clsidString);
	clsidString = NULL;
    }

    RegCloseKey(hkeyClsid);

    return res;
}

typedef HRESULT (WINAPI *DllRegisterServer_func)(void);

/* calls DllRegisterServer() for the Quartz DLL */
static void DEVENUM_RegisterQuartz(void)
{
    HANDLE hDLL = LoadLibraryA("quartz.dll");
    DllRegisterServer_func pDllRegisterServer = NULL;
    if (hDLL)
        pDllRegisterServer = (DllRegisterServer_func)GetProcAddress(hDLL, "DllRegisterServer");
    if (pDllRegisterServer)
    {
        HRESULT hr = pDllRegisterServer();
        if (FAILED(hr))
            ERR("Failed to register Quartz. Error was 0x%x)\n", hr);
    }
}
