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

#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;
    const GUID*                 guidCategory;
    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)
{
    HRESULT hres = S_OK;
    if (MSDMO_MAJOR_VERSION > 5)
    {
        hres = 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];

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

    return hres;
}

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

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

    hres = RegCreateKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0, NULL,
        REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hrkey, NULL);
    if (ERROR_SUCCESS != hres)
        goto lend;

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

    /* Set default Name value */
    hres = 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 */ 
        hres = RegCreateKeyExW(hkey, szDMOKeyed, 0, NULL,
            REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hckey, NULL);
        if (ERROR_SUCCESS != hres)
            goto lend;
        RegCloseKey(hckey);
    }

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

    RegCloseKey(hkey);

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

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

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


/***************************************************************
 * DMOUnregister (MSDMO.@)
 *
 * Unregister a DirectX Media Object.
 */
HRESULT WINAPI DMOUnregister(REFCLSID clsidDMO, REFGUID guidCategory)
{
    HRESULT hres;
    WCHAR szguid[64];
    HKEY hrkey = 0;
    HKEY hckey = 0;

    GUIDToString(szguid, clsidDMO);

    TRACE("%s %p\n", debugstr_w(szguid), guidCategory);

    hres = RegOpenKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0, KEY_WRITE, &hrkey);
    if (ERROR_SUCCESS != hres)
        goto lend;

    hres = RegDeleteKeyW(hrkey, szguid);
    if (ERROR_SUCCESS != hres)
        goto lend;

    hres = RegOpenKeyExW(hrkey, szDMOCategories, 0, KEY_WRITE, &hckey);
    if (ERROR_SUCCESS != hres)
        goto lend;

    hres = RegDeleteKeyW(hckey, szguid);
    if (ERROR_SUCCESS != hres)
        goto lend;

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

    return hres;
}


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

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

    hres = RegOpenKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 
        0, KEY_READ, &hrkey);
    if (ERROR_SUCCESS != hres)
        goto lend;

    hres = RegOpenKeyExW(hrkey, GUIDToString(szguid, clsidDMO),
        0, KEY_READ, &hkey);
    if (ERROR_SUCCESS != hres)
        goto lend;

    count = max_name_len * sizeof(WCHAR);
    hres = RegQueryValueExW(hkey, NULL, NULL, NULL, 
        (LPBYTE) szName, &count); 

    TRACE(" szName=%s\n", debugstr_w(szName));
lend:
    if (hkey)
        RegCloseKey(hrkey);
    if (hkey)
        RegCloseKey(hkey);

    return hres;
}


/**************************************************************************
*   IEnumDMOImpl_Destructor
*/
static BOOL IEnumDMOImpl_Destructor(IEnumDMOImpl* This)
{
    TRACE("%p\n", This);

    if (This->hkey)
        RegCloseKey(This->hkey);

    HeapFree(GetProcessHeap(), 0, This->pInTypes);
    HeapFree(GetProcessHeap(), 0, This->pOutTypes);

    return TRUE;
}


/**************************************************************************
 *  IEnumDMO_Constructor
 */
static IEnumDMO * IEnumDMO_Constructor(
    REFGUID guidCategory,
    DWORD dwFlags,
    DWORD cInTypes,
    const DMO_PARTIAL_MEDIATYPE *pInTypes,
    DWORD cOutTypes,
    const DMO_PARTIAL_MEDIATYPE *pOutTypes)
{
    UINT size;
    IEnumDMOImpl* lpedmo;
    BOOL ret = FALSE;

    lpedmo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IEnumDMOImpl));

    if (lpedmo)
    {
        lpedmo->ref = 1;
        lpedmo->IEnumDMO_iface.lpVtbl = &edmovt;
        lpedmo->index = -1;
	lpedmo->guidCategory = guidCategory;
	lpedmo->dwFlags = dwFlags;

        if (cInTypes > 0)
        {
            size = cInTypes * sizeof(DMO_PARTIAL_MEDIATYPE);
            lpedmo->pInTypes = HeapAlloc(GetProcessHeap(), 0, size);
            if (!lpedmo->pInTypes)
                goto lerr;
            memcpy(lpedmo->pInTypes, pInTypes, size);
            lpedmo->cInTypes = cInTypes;
        }

        if (cOutTypes > 0)
        {
            size = cOutTypes * sizeof(DMO_PARTIAL_MEDIATYPE);
            lpedmo->pOutTypes = HeapAlloc(GetProcessHeap(), 0, size);
            if (!lpedmo->pOutTypes)
                goto lerr;
            memcpy(lpedmo->pOutTypes, pOutTypes, size);
            lpedmo->cOutTypes = cOutTypes;
        }

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

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

lerr:
        if(!ret)
        {
            IEnumDMOImpl_Destructor(lpedmo);
            HeapFree(GetProcessHeap(),0,lpedmo);
            lpedmo = NULL;
        }
    }

    TRACE("returning %p\n", lpedmo);

    return (IEnumDMO*)lpedmo;
}


/******************************************************************************
 * IEnumDMO_fnAddRef
 */
static ULONG WINAPI IEnumDMO_fnAddRef(IEnumDMO * iface)
{
    IEnumDMOImpl *This = impl_from_IEnumDMO(iface);
    return InterlockedIncrement(&This->ref);
}


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

    *ppvObj = NULL;

    if(IsEqualIID(riid, &IID_IUnknown))
        *ppvObj = This;
    else if(IsEqualIID(riid, &IID_IEnumDMO))
        *ppvObj = This;

    if(*ppvObj)
    {
        IEnumDMO_fnAddRef(*ppvObj);
        return S_OK;
    }

    return E_NOINTERFACE;
}


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

    if (!refCount)
    {
        IEnumDMOImpl_Destructor(This);
        HeapFree(GetProcessHeap(),0,This);
    }
    return refCount;
}


/******************************************************************************
 * IEnumDMO_fnNext
 */
static HRESULT WINAPI IEnumDMO_fnNext(
    IEnumDMO * iface, 
    DWORD cItemsToFetch,
    CLSID * pCLSID,
    WCHAR ** Names,
    DWORD * pcItemsFetched)
{
    FILETIME ft;
    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;

    IEnumDMOImpl *This = impl_from_IEnumDMO(iface);

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

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

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

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

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

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

        wsprintfW(szKey, szCat2Fmt, szDMORootKey, szNextKey);
        hres = RegOpenKeyExW(HKEY_CLASSES_ROOT, szKey, 0, KEY_READ, &hkey);

        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 (ERROR_SUCCESS != hres)
            {
                RegCloseKey(hkey);
                continue;
            }

	    pInTypes = (DMO_PARTIAL_MEDIATYPE*) szValue;

            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 (ERROR_SUCCESS != hres)
            {
                RegCloseKey(hkey);
                continue;
            }

	    pOutTypes = (DMO_PARTIAL_MEDIATYPE*) szValue;

            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);
        hres = RegQueryValueExW(hkey, NULL, NULL, NULL, (LPBYTE) szValue, &len); 
        if (ERROR_SUCCESS == hres)
	{
            Names[count] = HeapAlloc(GetProcessHeap(), 0, (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);

    This->index += cItemsToSkip;

    return S_OK;
}


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

    This->index = -1;

    return S_OK;
}
 

/******************************************************************************
 * IEnumDMO_fnClone
 */
static HRESULT WINAPI IEnumDMO_fnClone(IEnumDMO * iface, IEnumDMO **ppEnum)
{
    IEnumDMOImpl *This = impl_from_IEnumDMO(iface);

    FIXME("(%p)->() to (%p)->() E_NOTIMPL\n", This, ppEnum);

  return E_NOTIMPL;
}


/***************************************************************
 * DMOEnum (MSDMO.@)
 *
 * Enumerate DirectX Media Objects in the registry.
 */
HRESULT WINAPI DMOEnum(
    REFGUID guidCategory,
    DWORD dwFlags,
    DWORD cInTypes,
    const DMO_PARTIAL_MEDIATYPE *pInTypes,
    DWORD cOutTypes,
    const DMO_PARTIAL_MEDIATYPE *pOutTypes,
    IEnumDMO **ppEnum)
{
    HRESULT hres = E_FAIL;

    TRACE("guidCategory=%p dwFlags=0x%08x cInTypes=%d cOutTypes=%d\n",
        guidCategory, dwFlags, cInTypes, cOutTypes);

    *ppEnum = IEnumDMO_Constructor(guidCategory, dwFlags, cInTypes,
        pInTypes, cOutTypes, pOutTypes);
    if (*ppEnum)
        hres = S_OK;

    return hres;
}


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;
        len = requested * sizeof(DMO_PARTIAL_MEDIATYPE);
        ret = RegQueryValueExW(root, key, NULL, NULL, (LPBYTE) types, &len);
        *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;
}
