/*
 * Copyright (C) 2003 Michael Günnewig
 * Copyright (C) 2003 CodeWeavers Inc. (Ulrich Czekalla)
 *
 * 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 <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winerror.h"
#include "winreg.h"
#include "objbase.h"
#include "wine/unicode.h"
#include "wine/debug.h"
#include "initguid.h"
#include "dmo.h"

WINE_DEFAULT_DEBUG_CHANNEL(msdmo);

#define MSDMO_MAJOR_VERSION 6

static const WCHAR szDMORootKey[] = 
{
    'D','i','r','e','c','t','S','h','o','w','\\',
    'M','e','d','i','a','O','b','j','e','c','t','s',0
}; 

static const WCHAR szDMOInputType[] =
{
    'I','n','p','u','t','T','y','p','e','s',0
};

static const WCHAR szDMOOutputType[] =
{
    'O','u','t','p','u','t','T','y','p','e','s',0
};

static const WCHAR szDMOKeyed[] =
{
    'K','e','y','e','d',0
};

static const WCHAR szDMOCategories[] =
{
    'C','a','t','e','g','o','r','i','e','s',0
};

static const WCHAR szGUIDFmt[] =
{
    '%','0','8','X','-','%','0','4','X','-','%','0','4','X','-','%','0',
    '2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2',
    'X','%','0','2','X','%','0','2','X','%','0','2','X',0
};

static const WCHAR szCat3Fmt[] =
{
    '%','s','\\','%','s','\\','%','s',0
};

static const WCHAR szCat2Fmt[] =
{
    '%','s','\\','%','s',0
};

static const WCHAR szToGuidFmt[] =
{
    '{','%','s','}',0
};


typedef struct
{
    IEnumDMO                    IEnumDMO_iface;
    LONG			ref;
    DWORD			index;
    GUID                        category;
    DWORD                       dwFlags;
    DWORD                       cInTypes;
    DMO_PARTIAL_MEDIATYPE       *pInTypes;
    DWORD                       cOutTypes;
    DMO_PARTIAL_MEDIATYPE       *pOutTypes;
    HKEY                        hkey;
} IEnumDMOImpl;

static inline IEnumDMOImpl *impl_from_IEnumDMO(IEnumDMO *iface)
{
    return CONTAINING_RECORD(iface, IEnumDMOImpl, IEnumDMO_iface);
}

static HRESULT read_types(HKEY root, LPCWSTR key, ULONG *supplied, ULONG requested, DMO_PARTIAL_MEDIATYPE* types);

static const IEnumDMOVtbl edmovt;

static LPWSTR GUIDToString(LPWSTR lpwstr, REFGUID lpcguid)
{
    wsprintfW(lpwstr, szGUIDFmt, lpcguid->Data1, lpcguid->Data2,
        lpcguid->Data3, lpcguid->Data4[0], lpcguid->Data4[1],
        lpcguid->Data4[2], lpcguid->Data4[3], lpcguid->Data4[4],
        lpcguid->Data4[5], lpcguid->Data4[6], lpcguid->Data4[7]);

    return lpwstr;
}

static BOOL IsMediaTypeEqual(const DMO_PARTIAL_MEDIATYPE* mt1, const DMO_PARTIAL_MEDIATYPE* mt2)
{

    return (IsEqualCLSID(&mt1->type, &mt2->type) ||
            IsEqualCLSID(&mt2->type, &GUID_NULL) ||
            IsEqualCLSID(&mt1->type, &GUID_NULL)) &&
            (IsEqualCLSID(&mt1->subtype, &mt2->subtype) ||
            IsEqualCLSID(&mt2->subtype, &GUID_NULL) ||
            IsEqualCLSID(&mt1->subtype, &GUID_NULL));
}

static HRESULT write_types(HKEY hkey, LPCWSTR name, const DMO_PARTIAL_MEDIATYPE* types, DWORD count)
{
    LONG ret;

    if (MSDMO_MAJOR_VERSION > 5)
    {
        ret = RegSetValueExW(hkey, name, 0, REG_BINARY, (const BYTE*) types,
                          count* sizeof(DMO_PARTIAL_MEDIATYPE));
    }
    else
    {
        HKEY skey1,skey2,skey3;
        DWORD index = 0;
        WCHAR szGuidKey[64];

        ret = RegCreateKeyExW(hkey, name, 0, NULL, REG_OPTION_NON_VOLATILE,
                               KEY_WRITE, NULL, &skey1, NULL);
        if (ret)
            return HRESULT_FROM_WIN32(ret);

        while (index < count)
        {
            GUIDToString(szGuidKey,&types[index].type);
            ret = RegCreateKeyExW(skey1, szGuidKey, 0, NULL,
                        REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &skey2, NULL);
            GUIDToString(szGuidKey,&types[index].subtype);
            ret = RegCreateKeyExW(skey2, szGuidKey, 0, NULL,
                        REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &skey3, NULL);
            RegCloseKey(skey3);
            RegCloseKey(skey2);
            index ++;
        }
        RegCloseKey(skey1);
    }

    return HRESULT_FROM_WIN32(ret);
}

/***************************************************************
 * DMORegister (MSDMO.@)
 *
 * Register a DirectX Media Object.
 */
HRESULT WINAPI DMORegister(
   LPCWSTR szName,
   REFCLSID clsidDMO,
   REFGUID guidCategory,
   DWORD dwFlags,
   DWORD cInTypes,
   const DMO_PARTIAL_MEDIATYPE *pInTypes,
   DWORD cOutTypes,
   const DMO_PARTIAL_MEDIATYPE *pOutTypes
)
{
    WCHAR szguid[64];
    HRESULT hres;
    HKEY hrkey = 0;
    HKEY hkey = 0;
    HKEY hckey = 0;
    HKEY hclskey = 0;
    LONG ret;

    TRACE("%s %s %s\n", debugstr_w(szName), debugstr_guid(clsidDMO), debugstr_guid(guidCategory));

    if (IsEqualGUID(guidCategory, &GUID_NULL))
        return E_INVALIDARG;

    ret = RegCreateKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0, NULL,
        REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hrkey, NULL);
    if (ret)
        return HRESULT_FROM_WIN32(ret);

    /* Create clsidDMO key under MediaObjects */ 
    ret = RegCreateKeyExW(hrkey, GUIDToString(szguid, clsidDMO), 0, NULL,
        REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, NULL);
    if (ret)
        goto lend;

    /* Set default Name value */
    ret = RegSetValueExW(hkey, NULL, 0, REG_SZ, (const BYTE*) szName,
        (strlenW(szName) + 1) * sizeof(WCHAR));

    /* Set InputTypes */
    hres = write_types(hkey, szDMOInputType, pInTypes, cInTypes);

    /* Set OutputTypes */
    hres = write_types(hkey, szDMOOutputType, pOutTypes, cOutTypes);

    if (dwFlags & DMO_REGISTERF_IS_KEYED)
    {
        /* Create Keyed key */ 
        ret = RegCreateKeyExW(hkey, szDMOKeyed, 0, NULL,
            REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hckey, NULL);
        if (ret)
            goto lend;
        RegCloseKey(hckey);
    }

    /* Register the category */
    ret = RegCreateKeyExW(hrkey, szDMOCategories, 0, NULL,
            REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hckey, NULL);
    if (ret)
        goto lend;

    RegCloseKey(hkey);

    ret = RegCreateKeyExW(hckey, GUIDToString(szguid, guidCategory), 0, NULL,
            REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, NULL);
    if (ret)
        goto lend;
    ret = RegCreateKeyExW(hkey, GUIDToString(szguid, clsidDMO), 0, NULL,
        REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hclskey, NULL);
    if (ret)
        goto lend;

lend:
    if (hkey)
        RegCloseKey(hkey);
    if (hckey)
        RegCloseKey(hckey);
    if (hclskey)
        RegCloseKey(hclskey);
    if (hrkey)
        RegCloseKey(hrkey);

    hres = HRESULT_FROM_WIN32(ret);
    TRACE(" hresult=0x%08x\n", hres);
    return hres;
}

static HRESULT unregister_dmo_from_category(const WCHAR *dmoW, const WCHAR *catW, HKEY categories)
{
    HKEY catkey;
    LONG ret;

    ret = RegOpenKeyExW(categories, catW, 0, KEY_WRITE, &catkey);
    if (!ret)
    {
        ret = RegDeleteKeyW(catkey, dmoW);
        RegCloseKey(catkey);
    }

    return !ret ? S_OK : S_FALSE;
}

/***************************************************************
 * DMOUnregister (MSDMO.@)
 *
 * Unregister a DirectX Media Object.
 */
HRESULT WINAPI DMOUnregister(REFCLSID dmo, REFGUID category)
{
    HKEY rootkey = 0, categorieskey = 0;
    WCHAR dmoW[64], catW[64];
    HRESULT hr = S_FALSE;
    LONG ret;

    TRACE("%s %s\n", debugstr_guid(dmo), debugstr_guid(category));

    ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0, KEY_WRITE, &rootkey);
    if (ret)
        return S_FALSE;

    GUIDToString(dmoW, dmo);
    RegDeleteKeyW(rootkey, dmoW);

    /* open 'Categories' */
    ret = RegOpenKeyExW(rootkey, szDMOCategories, 0, KEY_WRITE|KEY_ENUMERATE_SUB_KEYS, &categorieskey);
    RegCloseKey(rootkey);
    if (ret)
    {
        hr = HRESULT_FROM_WIN32(ret);
        goto lend;
    }

    /* remove from all categories */
    if (IsEqualGUID(category, &GUID_NULL))
    {
        DWORD index = 0, len = sizeof(catW)/sizeof(WCHAR);

        while (!RegEnumKeyExW(categorieskey, index++, catW, &len, NULL, NULL, NULL, NULL))
            hr = unregister_dmo_from_category(dmoW, catW, categorieskey);
    }
    else
    {
        GUIDToString(catW, category);
        hr = unregister_dmo_from_category(dmoW, catW, categorieskey);
    }

lend:
    if (categorieskey)
        RegCloseKey(categorieskey);

    return hr;
}


/***************************************************************
 * DMOGetName (MSDMO.@)
 *
 * Get DMO Name from the registry
 */
HRESULT WINAPI DMOGetName(REFCLSID clsidDMO, WCHAR name[])
{
    static const INT max_name_len = 80*sizeof(WCHAR);
    DWORD count = max_name_len;
    WCHAR szguid[64];
    HKEY hrkey, hkey;
    LONG ret;

    TRACE("%s %p\n", debugstr_guid(clsidDMO), name);

    if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0, KEY_READ, &hrkey))
        return E_FAIL;

    ret = RegOpenKeyExW(hrkey, GUIDToString(szguid, clsidDMO), 0, KEY_READ, &hkey);
    RegCloseKey(hrkey);
    if (ret)
        return E_FAIL;

    ret = RegQueryValueExW(hkey, NULL, NULL, NULL, (LPBYTE)name, &count);
    RegCloseKey(hkey);

    if (!ret && count > 1)
    {
        TRACE("name=%s\n", debugstr_w(name));
        return S_OK;
    }

    name[0] = 0;
    return S_FALSE;
}

static HRESULT dup_partial_mediatype(const DMO_PARTIAL_MEDIATYPE *types, DWORD count, DMO_PARTIAL_MEDIATYPE **ret)
{
    *ret = NULL;

    if (count == 0)
        return S_OK;

    *ret = HeapAlloc(GetProcessHeap(), 0, count*sizeof(*types));
    if (!*ret)
        return E_OUTOFMEMORY;

    memcpy(*ret, types, count*sizeof(*types));
    return S_OK;
}

/**************************************************************************
 *  IEnumDMO_Constructor
 */
static HRESULT IEnumDMO_Constructor(
    REFGUID guidCategory,
    DWORD dwFlags,
    DWORD cInTypes,
    const DMO_PARTIAL_MEDIATYPE *pInTypes,
    DWORD cOutTypes,
    const DMO_PARTIAL_MEDIATYPE *pOutTypes,
    IEnumDMO **obj)
{
    IEnumDMOImpl* lpedmo;
    HRESULT hr;
    LONG ret;

    *obj = NULL;

    lpedmo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IEnumDMOImpl));
    if (!lpedmo)
        return E_OUTOFMEMORY;

    lpedmo->IEnumDMO_iface.lpVtbl = &edmovt;
    lpedmo->ref = 1;
    lpedmo->index = -1;
    lpedmo->category = *guidCategory;
    lpedmo->dwFlags = dwFlags;
    lpedmo->cInTypes = cInTypes;
    lpedmo->cOutTypes = cOutTypes;

    hr = dup_partial_mediatype(pInTypes, cInTypes, &lpedmo->pInTypes);
    if (FAILED(hr))
        goto lerr;

    hr = dup_partial_mediatype(pOutTypes, cOutTypes, &lpedmo->pOutTypes);
    if (FAILED(hr))
        goto lerr;

    /* If not filtering by category enum from media objects root */
    if (IsEqualGUID(guidCategory, &GUID_NULL))
    {
        if ((ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0, KEY_READ, &lpedmo->hkey)))
            hr = HRESULT_FROM_WIN32(ret);
    }
    else
    {
        WCHAR szguid[64];
        WCHAR szKey[MAX_PATH];

        wsprintfW(szKey, szCat3Fmt, szDMORootKey, szDMOCategories, GUIDToString(szguid, guidCategory));
        if ((ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, szKey, 0, KEY_READ, &lpedmo->hkey)))
            hr = HRESULT_FROM_WIN32(ret);
    }

lerr:

    if (FAILED(hr))
        IEnumDMO_Release(&lpedmo->IEnumDMO_iface);
    else
    {
        TRACE("returning %p\n", lpedmo);
        *obj = &lpedmo->IEnumDMO_iface;
    }

    return hr;
}

/******************************************************************************
 * IEnumDMO_fnAddRef
 */
static ULONG WINAPI IEnumDMO_fnAddRef(IEnumDMO * iface)
{
    IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
    ULONG refCount = InterlockedIncrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, refCount);
    return refCount;
}

/**************************************************************************
 *  EnumDMO_QueryInterface
 */
static HRESULT WINAPI IEnumDMO_fnQueryInterface(IEnumDMO* iface, REFIID riid, void **ppvObj)
{
    IEnumDMOImpl *This = impl_from_IEnumDMO(iface);

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

    *ppvObj = NULL;

    if (IsEqualIID(riid, &IID_IEnumDMO) ||
        IsEqualIID(riid, &IID_IUnknown))
    {
        *ppvObj = iface;
        IEnumDMO_AddRef(iface);
    }

    return *ppvObj ? S_OK : E_NOINTERFACE;
}

/******************************************************************************
 * IEnumDMO_fnRelease
 */
static ULONG WINAPI IEnumDMO_fnRelease(IEnumDMO * iface)
{
    IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(%d)\n", This, refCount);

    if (!refCount)
    {
        if (This->hkey)
            RegCloseKey(This->hkey);
        HeapFree(GetProcessHeap(), 0, This->pInTypes);
        HeapFree(GetProcessHeap(), 0, This->pOutTypes);
        HeapFree(GetProcessHeap(), 0, This);
    }
    return refCount;
}


/******************************************************************************
 * IEnumDMO_fnNext
 */
static HRESULT WINAPI IEnumDMO_fnNext(
    IEnumDMO * iface, 
    DWORD cItemsToFetch,
    CLSID * pCLSID,
    WCHAR ** Names,
    DWORD * pcItemsFetched)
{
    HKEY hkey;
    WCHAR szNextKey[MAX_PATH];
    WCHAR szGuidKey[64];
    WCHAR szKey[MAX_PATH];
    WCHAR szValue[MAX_PATH];
    DWORD len;
    UINT count = 0;
    HRESULT hres = S_OK;
    LONG ret;

    IEnumDMOImpl *This = impl_from_IEnumDMO(iface);

    TRACE("(%p)->(%d %p %p %p)\n", This, cItemsToFetch, pCLSID, Names, pcItemsFetched);

    if (!pCLSID || !Names || !pcItemsFetched)
        return E_POINTER;

    while (count < cItemsToFetch)
    {
        This->index++;

        len = MAX_PATH;
        ret = RegEnumKeyExW(This->hkey, This->index, szNextKey, &len, NULL, NULL, NULL, NULL);
        if (ret != ERROR_SUCCESS)
        {
            hres = HRESULT_FROM_WIN32(ret);
            break;
        }

        TRACE("found %s\n", debugstr_w(szNextKey));

        if (!(This->dwFlags & DMO_ENUMF_INCLUDE_KEYED))
        {
            wsprintfW(szKey, szCat3Fmt, szDMORootKey, szNextKey, szDMOKeyed);
            ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, szKey, 0, KEY_READ, &hkey);
            if (ERROR_SUCCESS == ret)
            {
                RegCloseKey(hkey);
                /* Skip Keyed entries */
                continue;
            }
        }

        wsprintfW(szKey, szCat2Fmt, szDMORootKey, szNextKey);
        ret = RegOpenKeyExW(HKEY_CLASSES_ROOT, szKey, 0, KEY_READ, &hkey);
        TRACE("testing %s\n", debugstr_w(szKey));

        if (This->pInTypes)
        {
            UINT i, j;
            DWORD cInTypes;
            DMO_PARTIAL_MEDIATYPE* pInTypes;

            hres = read_types(hkey, szDMOInputType, &cInTypes,
                    sizeof(szValue)/sizeof(DMO_PARTIAL_MEDIATYPE),
                    (DMO_PARTIAL_MEDIATYPE*)szValue);

            if (FAILED(hres))
            {
                RegCloseKey(hkey);
                continue;
            }

	    pInTypes = (DMO_PARTIAL_MEDIATYPE*) szValue;

            TRACE("read %d intypes for %s:\n", cInTypes, debugstr_w(szKey));
            for (i = 0; i < cInTypes; i++) {
                TRACE("intype %d: type %s, subtype %s\n", i, debugstr_guid(&pInTypes[i].type),
                    debugstr_guid(&pInTypes[i].subtype));
            }

            for (i = 0; i < This->cInTypes; i++)
            {
                for (j = 0; j < cInTypes; j++) 
                {
                    if (IsMediaTypeEqual(&pInTypes[j], &This->pInTypes[i]))
		        break;
                }

		if (j >= cInTypes)
                    break;
            }

            if (i < This->cInTypes)
            {
                RegCloseKey(hkey);
                continue;
            }
        }

        if (This->pOutTypes)
        {
            UINT i, j;
            DWORD cOutTypes;
            DMO_PARTIAL_MEDIATYPE* pOutTypes;

            hres = read_types(hkey, szDMOOutputType, &cOutTypes,
                    sizeof(szValue)/sizeof(DMO_PARTIAL_MEDIATYPE),
                    (DMO_PARTIAL_MEDIATYPE*)szValue);

	    if (FAILED(hres))
            {
                RegCloseKey(hkey);
                continue;
            }

	    pOutTypes = (DMO_PARTIAL_MEDIATYPE*) szValue;

            TRACE("read %d outtypes for %s:\n", cOutTypes, debugstr_w(szKey));
            for (i = 0; i < cOutTypes; i++) {
                TRACE("outtype %d: type %s, subtype %s\n", i, debugstr_guid(&pOutTypes[i].type),
                    debugstr_guid(&pOutTypes[i].subtype));
            }

            for (i = 0; i < This->cOutTypes; i++)
            {
                for (j = 0; j < cOutTypes; j++) 
                {
                    if (IsMediaTypeEqual(&pOutTypes[j], &This->pOutTypes[i]))
		        break;
                }

		if (j >= cOutTypes)
                    break;
            }

            if (i < This->cOutTypes)
            {
                RegCloseKey(hkey);
                continue;
            }
        }

	/* Media object wasn't filtered so add it to return list */
        Names[count] = NULL;
	len = MAX_PATH * sizeof(WCHAR);
        ret = RegQueryValueExW(hkey, NULL, NULL, NULL, (LPBYTE)szValue, &len);
        if (ERROR_SUCCESS == ret)
	{
            Names[count] = CoTaskMemAlloc((strlenW(szValue) + 1) * sizeof(WCHAR));
	    if (Names[count])
                strcpyW(Names[count], szValue);
	}
        wsprintfW(szGuidKey,szToGuidFmt,szNextKey);
        CLSIDFromString(szGuidKey, &pCLSID[count]);

        TRACE("found match %s %s\n", debugstr_w(szValue), debugstr_w(szNextKey));
        RegCloseKey(hkey);
	count++;
    }

    *pcItemsFetched = count;
    if (*pcItemsFetched < cItemsToFetch)
        hres = S_FALSE;

    TRACE("<-- %i found\n",count);
    return hres;
}
 

/******************************************************************************
 * IEnumDMO_fnSkip
 */
static HRESULT WINAPI IEnumDMO_fnSkip(IEnumDMO * iface, DWORD cItemsToSkip)
{
    IEnumDMOImpl *This = impl_from_IEnumDMO(iface);

    TRACE("(%p)->(%d)\n", This, cItemsToSkip);
    This->index += cItemsToSkip;

    return S_OK;
}


/******************************************************************************
 * IEnumDMO_fnReset
 */
static HRESULT WINAPI IEnumDMO_fnReset(IEnumDMO * iface)
{
    IEnumDMOImpl *This = impl_from_IEnumDMO(iface);

    TRACE("(%p)\n", This);
    This->index = -1;

    return S_OK;
}
 

/******************************************************************************
 * IEnumDMO_fnClone
 */
static HRESULT WINAPI IEnumDMO_fnClone(IEnumDMO *iface, IEnumDMO **ppEnum)
{
    IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
    TRACE("(%p)->(%p)\n", This, ppEnum);
    return IEnumDMO_Constructor(&This->category, This->dwFlags, This->cInTypes, This->pInTypes,
        This->cOutTypes, This->pOutTypes, ppEnum);
}


/***************************************************************
 * DMOEnum (MSDMO.@)
 *
 * Enumerate DirectX Media Objects in the registry.
 */
HRESULT WINAPI DMOEnum(
    REFGUID category,
    DWORD flags,
    DWORD cInTypes,
    const DMO_PARTIAL_MEDIATYPE *pInTypes,
    DWORD cOutTypes,
    const DMO_PARTIAL_MEDIATYPE *pOutTypes,
    IEnumDMO **ppEnum)
{
    TRACE("%s 0x%08x %d %p %d %p %p\n", debugstr_guid(category), flags, cInTypes, pInTypes,
        cOutTypes, pOutTypes, ppEnum);

    if (TRACE_ON(msdmo))
    {
        DWORD i;
        if (cInTypes)
        {
            for (i = 0; i < cInTypes; i++)
                TRACE("intype %d - type %s, subtype %s\n", i, debugstr_guid(&pInTypes[i].type),
                    debugstr_guid(&pInTypes[i].subtype));
        }

        if (cOutTypes) {
            for (i = 0; i < cOutTypes; i++)
                TRACE("outtype %d - type %s, subtype %s\n", i, debugstr_guid(&pOutTypes[i].type),
                    debugstr_guid(&pOutTypes[i].subtype));
        }
    }

    return IEnumDMO_Constructor(category, flags, cInTypes,
        pInTypes, cOutTypes, pOutTypes, ppEnum);
}


static const IEnumDMOVtbl edmovt =
{
	IEnumDMO_fnQueryInterface,
	IEnumDMO_fnAddRef,
	IEnumDMO_fnRelease,
	IEnumDMO_fnNext,
	IEnumDMO_fnSkip,
	IEnumDMO_fnReset,
	IEnumDMO_fnClone,
};


HRESULT read_types(HKEY root, LPCWSTR key, ULONG *supplied, ULONG requested, DMO_PARTIAL_MEDIATYPE* types )
{
    HRESULT ret = S_OK;

    if (MSDMO_MAJOR_VERSION > 5)
    {
        DWORD len;
        LONG rc;

        len = requested * sizeof(DMO_PARTIAL_MEDIATYPE);
        rc = RegQueryValueExW(root, key, NULL, NULL, (LPBYTE) types, &len);
        ret = HRESULT_FROM_WIN32(rc);

        *supplied = len / sizeof(DMO_PARTIAL_MEDIATYPE);
    }
    else
    {
        HKEY hkey;
        WCHAR szGuidKey[64];

        *supplied = 0;
        if (ERROR_SUCCESS == RegOpenKeyExW(root, key, 0, KEY_READ, &hkey))
        {
          int index = 0;
          WCHAR szNextKey[MAX_PATH];
          DWORD len;
          LONG rc = ERROR_SUCCESS;

          while (rc == ERROR_SUCCESS)
          {
            len = MAX_PATH;
            rc = RegEnumKeyExW(hkey, index, szNextKey, &len, NULL, NULL, NULL, NULL);
            if (rc == ERROR_SUCCESS)
            {
              HKEY subk;
              int sub_index = 0;
              LONG rcs = ERROR_SUCCESS;
              WCHAR szSubKey[MAX_PATH];

              RegOpenKeyExW(hkey, szNextKey, 0, KEY_READ, &subk);
              while (rcs == ERROR_SUCCESS)
              {
                len = MAX_PATH;
                rcs = RegEnumKeyExW(subk, sub_index, szSubKey, &len, NULL, NULL, NULL, NULL);
                if (rcs == ERROR_SUCCESS)
                {
                  if (*supplied >= requested)
                  {
                    /* Bailing */
                    ret = S_FALSE;
                    rc = ERROR_MORE_DATA;
                    rcs = ERROR_MORE_DATA;
                    break;
                  }

                  wsprintfW(szGuidKey,szToGuidFmt,szNextKey);
                  CLSIDFromString(szGuidKey, &types[*supplied].type);
                  wsprintfW(szGuidKey,szToGuidFmt,szSubKey);
                  CLSIDFromString(szGuidKey, &types[*supplied].subtype);
                  TRACE("Adding type %s subtype %s at index %i\n",
                    debugstr_guid(&types[*supplied].type),
                    debugstr_guid(&types[*supplied].subtype),
                    *supplied);
                  (*supplied)++;
                }
                sub_index++;
              }
              index++;
            }
          }
          RegCloseKey(hkey);
        }
    }
    return ret;
}

/***************************************************************
 * DMOGetTypes (MSDMO.@)
 */
HRESULT WINAPI DMOGetTypes(REFCLSID clsidDMO,
               ULONG ulInputTypesRequested,
               ULONG* pulInputTypesSupplied,
               DMO_PARTIAL_MEDIATYPE* pInputTypes,
               ULONG ulOutputTypesRequested,
               ULONG* pulOutputTypesSupplied,
               DMO_PARTIAL_MEDIATYPE* pOutputTypes)
{
  HKEY root,hkey;
  HRESULT ret = S_OK;
  WCHAR szguid[64];

  TRACE ("(%s,%u,%p,%p,%u,%p,%p)\n", debugstr_guid(clsidDMO), ulInputTypesRequested,
        pulInputTypesSupplied, pInputTypes, ulOutputTypesRequested, pulOutputTypesSupplied,
        pOutputTypes);

  if (ERROR_SUCCESS != RegOpenKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0,
                                     KEY_READ, &root))
    return E_FAIL;

  if (ERROR_SUCCESS != RegOpenKeyExW(root,GUIDToString(szguid,clsidDMO) , 0,
                                     KEY_READ, &hkey))
  {
    RegCloseKey(root);
    return E_FAIL;
  }

  if (ulInputTypesRequested > 0)
  {
    ret = read_types(hkey, szDMOInputType, pulInputTypesSupplied, ulInputTypesRequested, pInputTypes );
  }
  else
    *pulInputTypesSupplied = 0;

  if (ulOutputTypesRequested > 0)
  {
    HRESULT ret2;
    ret2 = read_types(hkey, szDMOOutputType, pulOutputTypesSupplied, ulOutputTypesRequested, pOutputTypes );

    if (ret == S_OK)
        ret = ret2;
  }
  else
    *pulOutputTypesSupplied = 0;

  return ret;
}
