/*
 * IFilterMapper & IFilterMapper2 Implementations
 *
 * Copyright 2003 Robert Shearman
 * Copyright 2004 Christian Costa
 *
 * 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
 */

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "winerror.h"

#include "quartz_private.h"

#include "ole2.h"
#include "olectl.h"
#include "strmif.h"
#include "wine/unicode.h"
#include "uuids.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(quartz);

/* Unexposed IAMFilterData interface */
typedef struct IAMFilterData IAMFilterData;

typedef struct IAMFilterDataVtbl
{
    BEGIN_INTERFACE

    /*** IUnknown methods ***/
    HRESULT (STDMETHODCALLTYPE *QueryInterface)(
        IAMFilterData *This,
        REFIID riid,
        void **ppvObject);

    ULONG (STDMETHODCALLTYPE *AddRef)(
        IAMFilterData *This);

    ULONG (STDMETHODCALLTYPE *Release)(
        IAMFilterData *This);

    /*** IAMFilterData methods ***/
    HRESULT (STDMETHODCALLTYPE *ParseFilterData)(
        IAMFilterData *This,
        BYTE *pData,
        ULONG cb,
        BYTE **ppRegFilter2);

    HRESULT (STDMETHODCALLTYPE *CreateFilterData)(
        IAMFilterData* This,
        REGFILTER2 *prf2,
        BYTE **pRegFilterData,
        ULONG *pcb);

    END_INTERFACE
} IAMFilterDataVtbl;
struct IAMFilterData
{
    const IAMFilterDataVtbl *lpVtbl;
};
const GUID IID_IAMFilterData = {
 0x97f7c4d4, 0x547b, 0x4a5f, { 0x83,0x32, 0x53,0x64,0x30,0xad,0x2e,0x4d }
};


typedef struct FilterMapper2Impl
{
    const IFilterMapper2Vtbl *lpVtbl;
    const IFilterMapperVtbl  *lpVtblFilterMapper;
    const IAMFilterDataVtbl  *lpVtblAMFilterData;
    LONG refCount;
} FilterMapper2Impl;

static const IFilterMapper2Vtbl fm2vtbl;
static const IFilterMapperVtbl fmvtbl;
static const IAMFilterDataVtbl AMFilterDataVtbl;

static inline FilterMapper2Impl *impl_from_IFilterMapper( IFilterMapper *iface )
{
    return (FilterMapper2Impl *)((char*)iface - FIELD_OFFSET(FilterMapper2Impl, lpVtblFilterMapper));
}

static inline FilterMapper2Impl *impl_from_IAMFilterData( IAMFilterData *iface )
{
    return (FilterMapper2Impl *)((char*)iface - FIELD_OFFSET(FilterMapper2Impl, lpVtblAMFilterData));
}

static const WCHAR wszClsidSlash[] = {'C','L','S','I','D','\\',0};
static const WCHAR wszSlashInstance[] = {'\\','I','n','s','t','a','n','c','e','\\',0};
static const WCHAR wszSlash[] = {'\\',0};

/* CLSID property in media category Moniker */
static const WCHAR wszClsidName[] = {'C','L','S','I','D',0};
/* FriendlyName property in media category Moniker */
static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
/* Merit property in media category Moniker (CLSID_ActiveMovieCategories only) */
static const WCHAR wszMeritName[] = {'M','e','r','i','t',0};
/* FilterData property in media category Moniker (not CLSID_ActiveMovieCategories) */
static const WCHAR wszFilterDataName[] = {'F','i','l','t','e','r','D','a','t','a',0};
/* For filters registered with IFilterMapper */
static const WCHAR wszFilterSlash[] = {'F','i','l','t','e','r','\\',0};
static const WCHAR wszFilter[] = {'F','i','l','t','e','r',0};
/* For pins registered with IFilterMapper */
static const WCHAR wszPins[] = {'P','i','n','s',0};
static const WCHAR wszAllowedMany[] = {'A','l','l','o','w','e','d','M','a','n','y',0};
static const WCHAR wszAllowedZero[] = {'A','l','l','o','w','e','d','Z','e','r','o',0};
static const WCHAR wszDirection[] = {'D','i','r','e','c','t','i','o','n',0};
static const WCHAR wszIsRendered[] = {'I','s','R','e','n','d','e','r','e','d',0};
/* For types registered with IFilterMapper */
static const WCHAR wszTypes[] = {'T','y','p','e','s',0};


/* registry format for REGFILTER2 */
struct REG_RF
{
    DWORD dwVersion;
    DWORD dwMerit;
    DWORD dwPins;
    DWORD dwUnused;
};

struct REG_RFP
{
    BYTE signature[4]; /* e.g. "0pi3" */
    DWORD dwFlags;
    DWORD dwInstances;
    DWORD dwMediaTypes;
    DWORD dwMediums;
    DWORD bCategory; /* is there a category clsid? */
    /* optional: dwOffsetCategoryClsid */
};

struct REG_TYPE
{
    BYTE signature[4]; /* e.g. "0ty3" */
    DWORD dwUnused;
    DWORD dwOffsetMajor;
    DWORD dwOffsetMinor;
};

struct MONIKER_MERIT
{
    IMoniker * pMoniker;
    DWORD dwMerit;
};

struct Vector
{
    LPBYTE pData;
    int capacity; /* in bytes */
    int current; /* pointer to next free byte */
};

/* returns the position it was added at */
static int add_data(struct Vector * v, const BYTE * pData, int size)
{
    int index = v->current;
    if (v->current + size > v->capacity)
    {
        LPBYTE pOldData = v->pData;
        v->capacity = (v->capacity + size) * 2;
        v->pData = CoTaskMemAlloc(v->capacity);
        memcpy(v->pData, pOldData, v->current);
        CoTaskMemFree(pOldData);
    }
    memcpy(v->pData + v->current, pData, size);
    v->current += size;
    return index;
}

static int find_data(struct Vector * v, const BYTE * pData, int size)
{
    int index;
    for (index = 0; index < v->current; index++)
        if (!memcmp(v->pData + index, pData, size))
            return index;
    /* not found */
    return -1;
}

static void delete_vector(struct Vector * v)
{
    CoTaskMemFree(v->pData);
    v->current = 0;
    v->capacity = 0;
}

HRESULT FilterMapper2_create(IUnknown *pUnkOuter, LPVOID *ppObj)
{
    FilterMapper2Impl * pFM2impl;

    TRACE("(%p, %p)\n", pUnkOuter, ppObj);

    if (pUnkOuter)
        return CLASS_E_NOAGGREGATION;

    pFM2impl = CoTaskMemAlloc(sizeof(*pFM2impl));
    if (!pFM2impl)
        return E_OUTOFMEMORY;

    pFM2impl->lpVtbl = &fm2vtbl;
    pFM2impl->lpVtblFilterMapper = &fmvtbl;
    pFM2impl->lpVtblAMFilterData = &AMFilterDataVtbl;
    pFM2impl->refCount = 1;

    *ppObj = pFM2impl;

    TRACE("-- created at %p\n", pFM2impl);

    return S_OK;
}

HRESULT FilterMapper_create(IUnknown *pUnkOuter, LPVOID *ppObj)
{
    FilterMapper2Impl *pFM2impl;
    HRESULT hr;

    TRACE("(%p, %p)\n", pUnkOuter, ppObj);

    hr = FilterMapper2_create(pUnkOuter, (LPVOID*)&pFM2impl);
    if (FAILED(hr))
        return hr;

    *ppObj = &pFM2impl->lpVtblFilterMapper;

    return hr;
}

/*** IUnknown methods ***/

static HRESULT WINAPI FilterMapper2_QueryInterface(IFilterMapper2 * iface, REFIID riid, LPVOID *ppv)
{
    FilterMapper2Impl *This = (FilterMapper2Impl *)iface;

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

    *ppv = NULL;

    if (IsEqualIID(riid, &IID_IUnknown))
        *ppv = iface;
    else if (IsEqualIID(riid, &IID_IFilterMapper2))
        *ppv = iface;
    else if (IsEqualIID(riid, &IID_IFilterMapper))
        *ppv = &This->lpVtblFilterMapper;
    else if (IsEqualIID(riid, &IID_IAMFilterData))
        *ppv = &This->lpVtblAMFilterData;

    if (*ppv != NULL)
    {
        IUnknown_AddRef((IUnknown *)*ppv);
        return S_OK;
    }

    FIXME("No interface for %s\n", debugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI FilterMapper2_AddRef(IFilterMapper2 * iface)
{
    FilterMapper2Impl *This = (FilterMapper2Impl *)iface;
    ULONG refCount = InterlockedIncrement(&This->refCount);

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

    return refCount;
}

static ULONG WINAPI FilterMapper2_Release(IFilterMapper2 * iface)
{
    FilterMapper2Impl *This = (FilterMapper2Impl *)iface;
    ULONG refCount = InterlockedDecrement(&This->refCount);

    TRACE("(%p)->() Release from %d\n", This, refCount + 1);

    if (refCount == 0)
    {
        CoTaskMemFree(This);
        return 0;
    }
    return refCount;
}

/*** IFilterMapper2 methods ***/

static HRESULT WINAPI FilterMapper2_CreateCategory(
    IFilterMapper2 * iface,
    REFCLSID clsidCategory,
    DWORD dwCategoryMerit,
    LPCWSTR szDescription)
{
    LPWSTR wClsidAMCat = NULL;
    LPWSTR wClsidCategory = NULL;
    WCHAR wszKeyName[strlenW(wszClsidSlash) + strlenW(wszSlashInstance) + (CHARS_IN_GUID-1) * 2 + 1];
    HKEY hKey = NULL;
    LONG lRet;
    HRESULT hr;

    TRACE("(%s, %x, %s)\n", debugstr_guid(clsidCategory), dwCategoryMerit, debugstr_w(szDescription));

    hr = StringFromCLSID(&CLSID_ActiveMovieCategories, &wClsidAMCat);

    if (SUCCEEDED(hr))
    {
        hr = StringFromCLSID(clsidCategory, &wClsidCategory);
    }

    if (SUCCEEDED(hr))
    {
        strcpyW(wszKeyName, wszClsidSlash);
        strcatW(wszKeyName, wClsidAMCat);
        strcatW(wszKeyName, wszSlashInstance);
        strcatW(wszKeyName, wClsidCategory);

        lRet = RegCreateKeyExW(HKEY_CLASSES_ROOT, wszKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
        hr = HRESULT_FROM_WIN32(lRet);
    }

    if (SUCCEEDED(hr))
    {
        lRet = RegSetValueExW(hKey, wszFriendlyName, 0, REG_SZ, (const BYTE*)szDescription, (strlenW(szDescription) + 1) * sizeof(WCHAR));
        hr = HRESULT_FROM_WIN32(lRet);
    }

    if (SUCCEEDED(hr))
    {
        lRet = RegSetValueExW(hKey, wszClsidName, 0, REG_SZ, (LPBYTE)wClsidCategory, (strlenW(wClsidCategory) + 1) * sizeof(WCHAR));
        hr = HRESULT_FROM_WIN32(lRet);
    }

    if (SUCCEEDED(hr))
    {
        lRet = RegSetValueExW(hKey, wszMeritName, 0, REG_DWORD, (LPBYTE)&dwCategoryMerit, sizeof(dwCategoryMerit));
        hr = HRESULT_FROM_WIN32(lRet);
    }

    CloseHandle(hKey);
    CoTaskMemFree(wClsidCategory);
    CoTaskMemFree(wClsidAMCat);

    return hr;
}

static HRESULT WINAPI FilterMapper2_UnregisterFilter(
    IFilterMapper2 * iface,
    const CLSID *pclsidCategory,
    const OLECHAR *szInstance,
    REFCLSID Filter)
{
    WCHAR wszKeyName[MAX_PATH];
    LPWSTR wClsidCategory = NULL;
    LPWSTR wFilter = NULL;
    HRESULT hr;

    TRACE("(%p, %s, %s)\n", pclsidCategory, debugstr_w(szInstance), debugstr_guid(Filter));

    if (!pclsidCategory)
        pclsidCategory = &CLSID_LegacyAmFilterCategory;

    hr = StringFromCLSID(pclsidCategory, &wClsidCategory);

    if (SUCCEEDED(hr))
    {
        strcpyW(wszKeyName, wszClsidSlash);
        strcatW(wszKeyName, wClsidCategory);
        strcatW(wszKeyName, wszSlashInstance);
        if (szInstance)
            strcatW(wszKeyName, szInstance);
        else
        {
            hr = StringFromCLSID(Filter, &wFilter);
            if (SUCCEEDED(hr))
                strcatW(wszKeyName, wFilter);
        }
    }

    if (SUCCEEDED(hr))
    {
        LONG lRet = RegDeleteKeyW(HKEY_CLASSES_ROOT, wszKeyName);
        hr = HRESULT_FROM_WIN32(lRet);
    }

    CoTaskMemFree(wClsidCategory);
    CoTaskMemFree(wFilter);

    return hr;
}

static HRESULT FM2_WriteFriendlyName(IPropertyBag * pPropBag, LPCWSTR szName)
{
    VARIANT var;

    V_VT(&var) = VT_BSTR;
    V_UNION(&var, bstrVal) = (BSTR)szName;

    return IPropertyBag_Write(pPropBag, wszFriendlyName, &var);
}

static HRESULT FM2_WriteClsid(IPropertyBag * pPropBag, REFCLSID clsid)
{
    LPWSTR wszClsid = NULL;
    VARIANT var;
    HRESULT hr;

    hr = StringFromCLSID(clsid, &wszClsid);

    if (SUCCEEDED(hr))
    {
        V_VT(&var) = VT_BSTR;
        V_UNION(&var, bstrVal) = wszClsid;
        hr = IPropertyBag_Write(pPropBag, wszClsidName, &var);
    }
    CoTaskMemFree(wszClsid);
    return hr;
}

static HRESULT FM2_WriteFilterData(const REGFILTER2 * prf2, BYTE **ppData, ULONG *pcbData)
{
    int size = sizeof(struct REG_RF);
    unsigned int i;
    struct Vector mainStore = {NULL, 0, 0};
    struct Vector clsidStore = {NULL, 0, 0};
    struct REG_RF rrf;
    HRESULT hr = S_OK;

    rrf.dwVersion = prf2->dwVersion;
    rrf.dwMerit = prf2->dwMerit;
    rrf.dwPins = prf2->u.s1.cPins2;
    rrf.dwUnused = 0;

    add_data(&mainStore, (LPBYTE)&rrf, sizeof(rrf));

    for (i = 0; i < prf2->u.s1.cPins2; i++)
    {
        size += sizeof(struct REG_RFP);
        if (prf2->u.s1.rgPins2[i].clsPinCategory)
            size += sizeof(DWORD);
        size += prf2->u.s1.rgPins2[i].nMediaTypes * sizeof(struct REG_TYPE);
        size += prf2->u.s1.rgPins2[i].nMediums * sizeof(DWORD);
    }

    for (i = 0; i < prf2->u.s1.cPins2; i++)
    {
        struct REG_RFP rrfp;
        REGFILTERPINS2 rgPin2 = prf2->u.s1.rgPins2[i];
        unsigned int j;

        rrfp.signature[0] = '0';
        rrfp.signature[1] = 'p';
        rrfp.signature[2] = 'i';
        rrfp.signature[3] = '3';
        rrfp.signature[0] += i;
        rrfp.dwFlags = rgPin2.dwFlags;
        rrfp.dwInstances = rgPin2.cInstances;
        rrfp.dwMediaTypes = rgPin2.nMediaTypes;
        rrfp.dwMediums = rgPin2.nMediums;
        rrfp.bCategory = rgPin2.clsPinCategory ? 1 : 0;

        add_data(&mainStore, (LPBYTE)&rrfp, sizeof(rrfp));
        if (rrfp.bCategory)
        {
            DWORD index = find_data(&clsidStore, (const BYTE*)rgPin2.clsPinCategory, sizeof(CLSID));
            if (index == -1)
                index = add_data(&clsidStore, (const BYTE*)rgPin2.clsPinCategory, sizeof(CLSID));
            index += size;

            add_data(&mainStore, (LPBYTE)&index, sizeof(index));
        }

        for (j = 0; j < rgPin2.nMediaTypes; j++)
        {
            struct REG_TYPE rt;
            rt.signature[0] = '0';
            rt.signature[1] = 't';
            rt.signature[2] = 'y';
            rt.signature[3] = '3';
            rt.signature[0] += j;

            rt.dwUnused = 0;
            rt.dwOffsetMajor = find_data(&clsidStore, (const BYTE*)rgPin2.lpMediaType[j].clsMajorType, sizeof(CLSID));
            if (rt.dwOffsetMajor == -1)
                rt.dwOffsetMajor = add_data(&clsidStore, (const BYTE*)rgPin2.lpMediaType[j].clsMajorType, sizeof(CLSID));
            rt.dwOffsetMajor += size;
            rt.dwOffsetMinor = find_data(&clsidStore, (const BYTE*)rgPin2.lpMediaType[j].clsMinorType, sizeof(CLSID));
            if (rt.dwOffsetMinor == -1)
                rt.dwOffsetMinor = add_data(&clsidStore, (const BYTE*)rgPin2.lpMediaType[j].clsMinorType, sizeof(CLSID));
            rt.dwOffsetMinor += size;

            add_data(&mainStore, (LPBYTE)&rt, sizeof(rt));
        }

        for (j = 0; j < rgPin2.nMediums; j++)
        {
            DWORD index = find_data(&clsidStore, (const BYTE*)(rgPin2.lpMedium + j), sizeof(REGPINMEDIUM));
            if (index == -1)
                index = add_data(&clsidStore, (const BYTE*)(rgPin2.lpMedium + j), sizeof(REGPINMEDIUM));
            index += size;

            add_data(&mainStore, (LPBYTE)&index, sizeof(index));
        }
    }

    if (SUCCEEDED(hr))
    {
        *pcbData = mainStore.current + clsidStore.current;
        *ppData = CoTaskMemAlloc(*pcbData);
        if (!*ppData)
            hr = E_OUTOFMEMORY;
    }

    if (SUCCEEDED(hr))
    {
        memcpy(*ppData, mainStore.pData, mainStore.current);
        memcpy((*ppData) + mainStore.current, clsidStore.pData, clsidStore.current);
    }

    delete_vector(&mainStore);
    delete_vector(&clsidStore);
    return hr;
}

static HRESULT FM2_ReadFilterData(BYTE *pData, REGFILTER2 * prf2)
{
    HRESULT hr = S_OK;
    struct REG_RF * prrf;
    LPBYTE pCurrent;
    DWORD i;
    REGFILTERPINS2 * rgPins2;

    prrf = (struct REG_RF *)pData;
    pCurrent = pData;

    if (prrf->dwVersion != 2)
    {
        FIXME("Filter registry version %d not supported\n", prrf->dwVersion);
        ZeroMemory(prf2, sizeof(*prf2));
        hr = E_FAIL;
    }

    if (SUCCEEDED(hr))
    {
        TRACE("version = %d, merit = %x, #pins = %d, unused = %x\n",
            prrf->dwVersion, prrf->dwMerit, prrf->dwPins, prrf->dwUnused);

        prf2->dwVersion = prrf->dwVersion;
        prf2->dwMerit = prrf->dwMerit;
        prf2->u.s1.cPins2 = prrf->dwPins;
        rgPins2 = CoTaskMemAlloc(prrf->dwPins * sizeof(*rgPins2));
        prf2->u.s1.rgPins2 = rgPins2;
        pCurrent += sizeof(struct REG_RF);

        for (i = 0; i < prrf->dwPins; i++)
        {
            struct REG_RFP * prrfp = (struct REG_RFP *)pCurrent;
            REGPINTYPES * lpMediaType;
            REGPINMEDIUM * lpMedium;
            UINT j;

            /* FIXME: check signature */

            TRACE("\tsignature = %s\n", debugstr_an((const char*)prrfp->signature, 4));

            TRACE("\tpin[%d]: flags = %x, instances = %d, media types = %d, mediums = %d\n",
                i, prrfp->dwFlags, prrfp->dwInstances, prrfp->dwMediaTypes, prrfp->dwMediums);

            rgPins2[i].dwFlags = prrfp->dwFlags;
            rgPins2[i].cInstances = prrfp->dwInstances;
            rgPins2[i].nMediaTypes = prrfp->dwMediaTypes;
            rgPins2[i].nMediums = prrfp->dwMediums;
            pCurrent += sizeof(struct REG_RFP);
            if (prrfp->bCategory)
            {
                CLSID * clsCat = CoTaskMemAlloc(sizeof(CLSID));
                memcpy(clsCat, pData + *(DWORD*)(pCurrent), sizeof(CLSID));
                pCurrent += sizeof(DWORD);
                rgPins2[i].clsPinCategory = clsCat;
            }
            else
                rgPins2[i].clsPinCategory = NULL;

            if (rgPins2[i].nMediaTypes > 0)
                lpMediaType = CoTaskMemAlloc(rgPins2[i].nMediaTypes * sizeof(*lpMediaType));
            else
                lpMediaType = NULL;

            rgPins2[i].lpMediaType = lpMediaType;

            for (j = 0; j < rgPins2[i].nMediaTypes; j++)
            {
                struct REG_TYPE * prt = (struct REG_TYPE *)pCurrent;
                CLSID * clsMajor = CoTaskMemAlloc(sizeof(CLSID));
                CLSID * clsMinor = CoTaskMemAlloc(sizeof(CLSID));

                /* FIXME: check signature */
                TRACE("\t\tsignature = %s\n", debugstr_an((const char*)prt->signature, 4));

                memcpy(clsMajor, pData + prt->dwOffsetMajor, sizeof(CLSID));
                memcpy(clsMinor, pData + prt->dwOffsetMinor, sizeof(CLSID));

                lpMediaType[j].clsMajorType = clsMajor;
                lpMediaType[j].clsMinorType = clsMinor;

                pCurrent += sizeof(*prt);
            }

            if (rgPins2[i].nMediums > 0)
                lpMedium = CoTaskMemAlloc(rgPins2[i].nMediums * sizeof(*lpMedium));
            else
                lpMedium = NULL;

            rgPins2[i].lpMedium = lpMedium;

            for (j = 0; j < rgPins2[i].nMediums; j++)
            {
                DWORD dwOffset = *(DWORD *)pCurrent;

                memcpy(lpMedium + j, pData + dwOffset, sizeof(REGPINMEDIUM));

                pCurrent += sizeof(dwOffset);
            }
        }

    }

    return hr;
}

static void FM2_DeleteRegFilter(REGFILTER2 * prf2)
{
    UINT i;
    for (i = 0; i < prf2->u.s1.cPins2; i++)
    {
        UINT j;
        if (prf2->u.s1.rgPins2[i].clsPinCategory)
            CoTaskMemFree((LPVOID)prf2->u.s1.rgPins2[i].clsPinCategory);

        for (j = 0; j < prf2->u.s1.rgPins2[i].nMediaTypes; j++)
        {
            CoTaskMemFree((LPVOID)prf2->u.s1.rgPins2[i].lpMediaType[j].clsMajorType);
            CoTaskMemFree((LPVOID)prf2->u.s1.rgPins2[i].lpMediaType[j].clsMinorType);
        }
        CoTaskMemFree((LPVOID)prf2->u.s1.rgPins2[i].lpMedium);
    }
}

static HRESULT WINAPI FilterMapper2_RegisterFilter(
    IFilterMapper2 * iface,
    REFCLSID clsidFilter,
    LPCWSTR szName,
    IMoniker **ppMoniker,
    const CLSID *pclsidCategory,
    const OLECHAR *szInstance,
    const REGFILTER2 *prf2)
{
    IParseDisplayName * pParser = NULL;
    IBindCtx * pBindCtx = NULL;
    IMoniker * pMoniker = NULL;
    IPropertyBag * pPropBag = NULL;
    HRESULT hr;
    LPWSTR pwszParseName = NULL;
    LPWSTR pCurrent;
    static const WCHAR wszDevice[] = {'@','d','e','v','i','c','e',':','s','w',':',0};
    int nameLen;
    ULONG ulEaten;
    LPWSTR szClsidTemp = NULL;
    REGFILTER2 regfilter2;
    REGFILTERPINS2* pregfp2 = NULL;

    TRACE("(%s, %s, %p, %s, %s, %p)\n",
        debugstr_guid(clsidFilter),
        debugstr_w(szName),
        ppMoniker,
        debugstr_guid(pclsidCategory),
        debugstr_w(szInstance),
        prf2);

    if (prf2->dwVersion == 2)
    {
        regfilter2 = *prf2;
    }
    else if (prf2->dwVersion == 1)
    {
        ULONG i;
        DWORD flags;
        /* REGFILTER2 structure is converted from version 1 to 2. Tested on Win2k. */
        regfilter2.dwVersion = 2;
        regfilter2.dwMerit = prf2->dwMerit;
        regfilter2.u.s1.cPins2 = prf2->u.s.cPins;
        pregfp2 = (REGFILTERPINS2*) CoTaskMemAlloc(prf2->u.s.cPins * sizeof(REGFILTERPINS2));
        regfilter2.u.s1.rgPins2 = pregfp2;
        for (i = 0; i < prf2->u.s.cPins; i++)
        {
            flags = 0;
            if (prf2->u.s.rgPins[i].bRendered)
                flags |= REG_PINFLAG_B_RENDERER;
            if (prf2->u.s.rgPins[i].bOutput)
                flags |= REG_PINFLAG_B_OUTPUT;
            if (prf2->u.s.rgPins[i].bZero)
                flags |= REG_PINFLAG_B_ZERO;
            if (prf2->u.s.rgPins[i].bMany)
                flags |= REG_PINFLAG_B_MANY;
            pregfp2[i].dwFlags = flags;
            pregfp2[i].cInstances = 1;
            pregfp2[i].nMediaTypes = prf2->u.s.rgPins[i].nMediaTypes;
            pregfp2[i].lpMediaType = prf2->u.s.rgPins[i].lpMediaType;
            pregfp2[i].nMediums = 0;
            pregfp2[i].lpMedium = NULL;
            pregfp2[i].clsPinCategory = NULL;
        }
    }
    else
    {
        FIXME("dwVersion other that 1 or 2 not supported at the moment\n");
        return E_NOTIMPL;
    }

    if (ppMoniker)
        *ppMoniker = NULL;

    if (!pclsidCategory)
        /* MSDN mentions the inexistent CLSID_ActiveMovieFilters GUID.
         * In fact this is the CLSID_LegacyAmFilterCategory one */
        pclsidCategory = &CLSID_LegacyAmFilterCategory;

    /* sizeof... will include the null terminator and
     * the + 1 is for the separator ('\\'). The -1 is
     * because CHARS_IN_GUID includes the null terminator
     */
    nameLen = sizeof(wszDevice)/sizeof(wszDevice[0]) + CHARS_IN_GUID - 1 + 1;

    if (szInstance)
        nameLen += strlenW(szInstance);
    else
        nameLen += CHARS_IN_GUID - 1; /* CHARS_IN_GUID includes null terminator */

    pCurrent = pwszParseName = CoTaskMemAlloc(nameLen*sizeof(WCHAR));
    if (!pwszParseName)
        return E_OUTOFMEMORY;

    strcpyW(pwszParseName, wszDevice);
    pCurrent += strlenW(wszDevice);

    hr = StringFromCLSID(pclsidCategory, &szClsidTemp);

    if (SUCCEEDED(hr))
    {
        memcpy(pCurrent, szClsidTemp, CHARS_IN_GUID * sizeof(WCHAR));
        pCurrent += CHARS_IN_GUID - 1;
        pCurrent[0] = '\\';

        if (szInstance)
            strcpyW(pCurrent+1, szInstance);
        else
        {
            CoTaskMemFree(szClsidTemp);
            szClsidTemp = NULL;

            hr = StringFromCLSID(clsidFilter, &szClsidTemp);
            if (SUCCEEDED(hr))
                strcpyW(pCurrent+1, szClsidTemp);
        }
    }

    if (SUCCEEDED(hr))
        hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (LPVOID *)&pParser);

    if (SUCCEEDED(hr))
        hr = CreateBindCtx(0, &pBindCtx);

    if (SUCCEEDED(hr))
        hr = IParseDisplayName_ParseDisplayName(pParser, pBindCtx, pwszParseName, &ulEaten, &pMoniker);

    if (pBindCtx)
        IBindCtx_Release(pBindCtx);
    if (pParser)
        IParseDisplayName_Release(pParser);

    if (SUCCEEDED(hr))
        hr = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID)&pPropBag);

    if (SUCCEEDED(hr))
        hr = FM2_WriteFriendlyName(pPropBag, szName);

    if (SUCCEEDED(hr))
        hr = FM2_WriteClsid(pPropBag, clsidFilter);

    if (SUCCEEDED(hr))
    {
        BYTE *pData;
        ULONG cbData;

        hr = FM2_WriteFilterData(&regfilter2, &pData, &cbData);
        if (SUCCEEDED(hr))
        {
            VARIANT var;
            SAFEARRAY *psa;
            SAFEARRAYBOUND saBound;

            saBound.lLbound = 0;
            saBound.cElements = cbData;
            psa = SafeArrayCreate(VT_UI1, 1, &saBound);
            if (!psa)
            {
                ERR("Couldn't create SAFEARRAY\n");
                hr = E_FAIL;
            }

            if (SUCCEEDED(hr))
            {
                LPBYTE pbSAData;
                hr = SafeArrayAccessData(psa, (LPVOID *)&pbSAData);
                if (SUCCEEDED(hr))
                {
                    memcpy(pbSAData, pData, cbData);
                    hr = SafeArrayUnaccessData(psa);
                }
            }

            V_VT(&var) = VT_ARRAY | VT_UI1;
            V_UNION(&var, parray) = psa;

            if (SUCCEEDED(hr))
                hr = IPropertyBag_Write(pPropBag, wszFilterDataName, &var);

            if (psa)
                SafeArrayDestroy(psa);
            CoTaskMemFree(pData);
        }
    }

    if (pPropBag)
        IPropertyBag_Release(pPropBag);
    CoTaskMemFree(szClsidTemp);

    if (SUCCEEDED(hr) && ppMoniker)
        *ppMoniker = pMoniker;
    else if (pMoniker)
        IMoniker_Release(pMoniker);

    CoTaskMemFree(pregfp2);

    TRACE("-- returning %x\n", hr);

    return hr;
}

/* internal helper function */
static BOOL MatchTypes(
    BOOL bExactMatch,
    DWORD nPinTypes,
    const REGPINTYPES * pPinTypes,
    DWORD nMatchTypes,
    const GUID * pMatchTypes)
{
    BOOL bMatch = FALSE;
    DWORD j;

    if ((nMatchTypes == 0) && (nPinTypes > 0))
        bMatch = TRUE;

    for (j = 0; j < nPinTypes; j++)
    {
        DWORD i;
        for (i = 0; i < nMatchTypes*2; i+=2)
        {
            if (((!bExactMatch && IsEqualGUID(pPinTypes[j].clsMajorType, &GUID_NULL)) || IsEqualGUID(&pMatchTypes[i], &GUID_NULL) || IsEqualGUID(pPinTypes[j].clsMajorType, &pMatchTypes[i])) &&
                ((!bExactMatch && IsEqualGUID(pPinTypes[j].clsMinorType, &GUID_NULL)) || IsEqualGUID(&pMatchTypes[i+1], &GUID_NULL) || IsEqualGUID(pPinTypes[j].clsMinorType, &pMatchTypes[i+1])))
            {
                bMatch = TRUE;
                break;
            }
        }
    }
    return bMatch;
}

/* internal helper function for qsort of MONIKER_MERIT array */
static int mm_compare(const void * left, const void * right)
{
    const struct MONIKER_MERIT * mmLeft = (const struct MONIKER_MERIT *)left;
    const struct MONIKER_MERIT * mmRight = (const struct MONIKER_MERIT *)right;

    if (mmLeft->dwMerit == mmRight->dwMerit)
        return 0;
    if (mmLeft->dwMerit > mmRight->dwMerit)
        return -1;
    return 1;
}

/* NOTES:
 *   Exact match means whether or not to treat GUID_NULL's in filter data as wild cards
 *    (GUID_NULL's in input to function automatically treated as wild cards)
 *   Input/Output needed means match only on criteria if TRUE (with zero input types
 *    meaning match any input/output pin as long as one exists), otherwise match any
 *    filter that meets the rest of the requirements.
 */
static HRESULT WINAPI FilterMapper2_EnumMatchingFilters(
    IFilterMapper2 * iface,
    IEnumMoniker **ppEnum,
    DWORD dwFlags,
    BOOL bExactMatch,
    DWORD dwMerit,
    BOOL bInputNeeded,
    DWORD cInputTypes,
    const GUID *pInputTypes,
    const REGPINMEDIUM *pMedIn,
    const CLSID *pPinCategoryIn,
    BOOL bRender,
    BOOL bOutputNeeded,
    DWORD cOutputTypes,
    const GUID *pOutputTypes,
    const REGPINMEDIUM *pMedOut,
    const CLSID *pPinCategoryOut)
{
    ICreateDevEnum * pCreateDevEnum;
    IMoniker * pMonikerCat;
    IEnumMoniker * pEnumCat;
    HRESULT hr;
    struct Vector monikers = {NULL, 0, 0};

    TRACE("(%p, %x, %s, %x, %s, %d, %p, %p, %p, %s, %s, %p, %p, %p)\n",
        ppEnum,
        dwFlags,
        bExactMatch ? "true" : "false",
        dwMerit,
        bInputNeeded ? "true" : "false",
        cInputTypes,
        pInputTypes,
        pMedIn,
        pPinCategoryIn,
        bRender ? "true" : "false",
        bOutputNeeded ? "true" : "false",
        pOutputTypes,
        pMedOut,
        pPinCategoryOut);

    if (dwFlags != 0)
    {
        FIXME("dwFlags = %x not implemented\n", dwFlags);
    }

    *ppEnum = NULL;

    hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, &IID_ICreateDevEnum, (LPVOID*)&pCreateDevEnum);

    if (SUCCEEDED(hr))
        hr = ICreateDevEnum_CreateClassEnumerator(pCreateDevEnum, &CLSID_ActiveMovieCategories, &pEnumCat, 0);

    while (IEnumMoniker_Next(pEnumCat, 1, &pMonikerCat, NULL) == S_OK)
    {
        IPropertyBag * pPropBagCat = NULL;
        VARIANT var;
        HRESULT hrSub; /* this is so that one buggy filter
                          doesn't make the whole lot fail */

        VariantInit(&var);

        hrSub = IMoniker_BindToStorage(pMonikerCat, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&pPropBagCat);

        if (SUCCEEDED(hrSub))
            hrSub = IPropertyBag_Read(pPropBagCat, wszMeritName, &var, NULL);

        if (SUCCEEDED(hrSub) && (V_UNION(&var, ulVal) >= dwMerit))
        {
            CLSID clsidCat;
            IEnumMoniker * pEnum;
            IMoniker * pMoniker;

            VariantClear(&var);

            if (TRACE_ON(quartz))
            {
                VARIANT temp;
                V_VT(&temp) = VT_EMPTY;
                IPropertyBag_Read(pPropBagCat, wszFriendlyName, &temp, NULL);
                TRACE("Considering category %s\n", debugstr_w(V_UNION(&temp, bstrVal)));
                VariantClear(&temp);
            }

            hrSub = IPropertyBag_Read(pPropBagCat, wszClsidName, &var, NULL);

            if (SUCCEEDED(hrSub))
                hrSub = CLSIDFromString(V_UNION(&var, bstrVal), &clsidCat);

            if (SUCCEEDED(hrSub))
                hrSub = ICreateDevEnum_CreateClassEnumerator(pCreateDevEnum, &clsidCat, &pEnum, 0);

            if (hrSub == S_OK)
            {
                while (IEnumMoniker_Next(pEnum, 1, &pMoniker, NULL) == S_OK)
                {
                    IPropertyBag * pPropBag = NULL;
                    VARIANT var;
                    BYTE *pData = NULL;
                    REGFILTER2 rf2;
                    DWORD i;
                    BOOL bInputMatch = !bInputNeeded;
                    BOOL bOutputMatch = !bOutputNeeded;

                    ZeroMemory(&rf2, sizeof(rf2));
                    VariantInit(&var);

                    hrSub = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&pPropBag);

                    if (TRACE_ON(quartz))
                    {
                        VARIANT temp;
                        V_VT(&temp) = VT_EMPTY;
                        IPropertyBag_Read(pPropBag, wszFriendlyName, &temp, NULL);
                        TRACE("Considering filter %s\n", debugstr_w(V_UNION(&temp, bstrVal)));
                        VariantClear(&temp);
                    }

                    if (SUCCEEDED(hrSub))
                    {
                        V_VT(&var) = VT_ARRAY | VT_UI1;
                        hrSub = IPropertyBag_Read(pPropBag, wszFilterDataName, &var, NULL);
                    }

                    if (SUCCEEDED(hrSub))
                        hrSub = SafeArrayAccessData(V_UNION(&var, parray), (LPVOID*)&pData);

                    if (SUCCEEDED(hrSub))
                        hrSub = FM2_ReadFilterData(pData, &rf2);

                    if (pData)
                        SafeArrayUnaccessData(V_UNION(&var, parray));

                    VariantClear(&var);

                    /* Logic used for bInputMatch expression:
                     * There exists some pin such that bInputNeeded implies (pin is an input and
                     * (bRender implies pin has render flag) and major/minor types members of
                     * pInputTypes )
                     * bOutputMatch is similar, but without the "bRender implies ..." part
                     * and substituting variables names containing input for output
                     */

                    /* determine whether filter meets requirements */
                    if (SUCCEEDED(hrSub) && (rf2.dwMerit >= dwMerit))
                    {
                        for (i = 0; (i < rf2.u.s1.cPins2) && (!bInputMatch || !bOutputMatch); i++)
                        {
                            const REGFILTERPINS2 * rfp2 = rf2.u.s1.rgPins2 + i;

                            bInputMatch = bInputMatch || (!(rfp2->dwFlags & REG_PINFLAG_B_OUTPUT) &&
                                (!bRender || (rfp2->dwFlags & REG_PINFLAG_B_RENDERER)) &&
                                MatchTypes(bExactMatch, rfp2->nMediaTypes, rfp2->lpMediaType, cInputTypes, pInputTypes));
                            bOutputMatch = bOutputMatch || ((rfp2->dwFlags & REG_PINFLAG_B_OUTPUT) &&
                                MatchTypes(bExactMatch, rfp2->nMediaTypes, rfp2->lpMediaType, cOutputTypes, pOutputTypes));
                        }

                        if (bInputMatch && bOutputMatch)
                        {
                            struct MONIKER_MERIT mm = {pMoniker, rf2.dwMerit};
                            IMoniker_AddRef(pMoniker);
                            add_data(&monikers, (LPBYTE)&mm, sizeof(mm));
                        }
                    }

                    FM2_DeleteRegFilter(&rf2);
                    if (pPropBag)
                        IPropertyBag_Release(pPropBag);
                    IMoniker_Release(pMoniker);
                }
                IEnumMoniker_Release(pEnum);
            }
        }

        VariantClear(&var);
        if (pPropBagCat)
            IPropertyBag_Release(pPropBagCat);
        IMoniker_Release(pMonikerCat);
    }

    if (SUCCEEDED(hr))
    {
        IMoniker ** ppMoniker;
        unsigned int i;
        ULONG nMonikerCount = monikers.current / sizeof(struct MONIKER_MERIT);

        /* sort the monikers in descending merit order */
        qsort(monikers.pData, nMonikerCount,
              sizeof(struct MONIKER_MERIT),
              mm_compare);

        /* construct an IEnumMoniker interface */
        ppMoniker = CoTaskMemAlloc(nMonikerCount * sizeof(IMoniker *));
        for (i = 0; i < nMonikerCount; i++)
        {
            /* no need to AddRef here as already AddRef'd above */
            ppMoniker[i] = ((struct MONIKER_MERIT *)monikers.pData)[i].pMoniker;
        }
        hr = EnumMonikerImpl_Create(ppMoniker, nMonikerCount, ppEnum);
        CoTaskMemFree(ppMoniker);
    }

    delete_vector(&monikers);
    IEnumMoniker_Release(pEnumCat);
    ICreateDevEnum_Release(pCreateDevEnum);

    return hr;
}

static const IFilterMapper2Vtbl fm2vtbl =
{

    FilterMapper2_QueryInterface,
    FilterMapper2_AddRef,
    FilterMapper2_Release,

    FilterMapper2_CreateCategory,
    FilterMapper2_UnregisterFilter,
    FilterMapper2_RegisterFilter,
    FilterMapper2_EnumMatchingFilters
};

/*** IUnknown methods ***/

static HRESULT WINAPI FilterMapper_QueryInterface(IFilterMapper * iface, REFIID riid, LPVOID *ppv)
{
    FilterMapper2Impl *This = impl_from_IFilterMapper(iface);

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

    return FilterMapper2_QueryInterface((IFilterMapper2*)&This->lpVtbl, riid, ppv);
}

static ULONG WINAPI FilterMapper_AddRef(IFilterMapper * iface)
{
    FilterMapper2Impl *This = impl_from_IFilterMapper(iface);

    return FilterMapper2_AddRef((IFilterMapper2*)This);
}

static ULONG WINAPI FilterMapper_Release(IFilterMapper * iface)
{
    FilterMapper2Impl *This = impl_from_IFilterMapper(iface);

    return FilterMapper2_Release((IFilterMapper2*)This);
}

/*** IFilterMapper methods ***/

static HRESULT WINAPI FilterMapper_EnumMatchingFilters(
    IFilterMapper * iface,
    IEnumRegFilters **ppEnum,
    DWORD dwMerit,
    BOOL bInputNeeded,
    CLSID clsInMaj,
    CLSID clsInSub,
    BOOL bRender,
    BOOL bOutputNeeded,
    CLSID clsOutMaj,
    CLSID clsOutSub)
{
    FilterMapper2Impl *This = impl_from_IFilterMapper(iface);
    GUID InputType[2];
    GUID OutputType[2];
    IEnumMoniker* ppEnumMoniker;
    IMoniker* IMon;
    ULONG nb;
    ULONG idx = 0, nb_mon = 0;
    REGFILTER* regfilters;
    HRESULT hr;

    TRACE("(%p/%p)->(%p, %x, %s, %s, %s, %s, %s, %s, %s) stub!\n",
        iface,This,
        ppEnum,
        dwMerit,
        bInputNeeded ? "true" : "false",
        debugstr_guid(&clsInMaj),
        debugstr_guid(&clsInSub),
        bRender ? "true" : "false",
        bOutputNeeded ? "true" : "false",
        debugstr_guid(&clsOutMaj),
        debugstr_guid(&clsOutSub));

    InputType[0] = clsInMaj;
    InputType[1] = clsInSub;
    OutputType[0] = clsOutMaj;
    OutputType[1] = clsOutSub;

    hr = IFilterMapper2_EnumMatchingFilters((IFilterMapper2*)This,
                                       &ppEnumMoniker,
                                       0,
                                       TRUE,
                                       dwMerit,
                                       bInputNeeded,
                                       1,
                                       InputType,
                                       NULL,
                                       &GUID_NULL,
                                       bRender,
                                       bOutputNeeded,
                                       1,
                                       OutputType,
                                       NULL,
                                       &GUID_NULL);

    if (!SUCCEEDED(hr))
        return hr;
    
    while(IEnumMoniker_Next(ppEnumMoniker, 1, &IMon, &nb) == S_OK)
    {
        IMoniker_Release(IMon);
        nb_mon++;
    }

    *ppEnum = NULL;
    if (!nb_mon)
    {
        IEnumMoniker_Release(ppEnumMoniker);
        return IEnumRegFiltersImpl_Construct(NULL, 0, ppEnum);
    }

    regfilters = CoTaskMemAlloc(nb_mon * sizeof(REGFILTER));
    if (!regfilters)
    {
        IEnumMoniker_Release(ppEnumMoniker);
        return E_OUTOFMEMORY;
    }
    
    IEnumMoniker_Reset(ppEnumMoniker);
    while(IEnumMoniker_Next(ppEnumMoniker, 1, &IMon, &nb) == S_OK)
    {
        IPropertyBag * pPropBagCat = NULL;
        VARIANT var;
        HRESULT hrSub;
        GUID clsid;
        int len;

        VariantInit(&var);
        V_VT(&var) = VT_BSTR;

        hrSub = IMoniker_BindToStorage(IMon, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&pPropBagCat);

        if (SUCCEEDED(hrSub))
            hrSub = IPropertyBag_Read(pPropBagCat, wszClsidName, &var, NULL);

        if (SUCCEEDED(hrSub))
            hrSub = CLSIDFromString(V_UNION(&var, bstrVal), &clsid);

        if (SUCCEEDED(hrSub))
            hrSub = IPropertyBag_Read(pPropBagCat, wszFriendlyName, &var, NULL);

        if (SUCCEEDED(hrSub))
        {
            len = (strlenW((WCHAR*)&V_UNION(&var, bstrVal))+1) * sizeof(WCHAR);
            if (!(regfilters[idx].Name = CoTaskMemAlloc(len*2)))
                hr = E_OUTOFMEMORY;
        }

        if (SUCCEEDED(hrSub))
        {
            memcpy(regfilters[idx].Name, &V_UNION(&var, bstrVal), len);
            regfilters[idx].Clsid = clsid;
            idx++;
        }

        if (pPropBagCat)
            IPropertyBag_Release(pPropBagCat);
        IMoniker_Release(IMon);
    }

    /* In case of release all resources */
    if (!SUCCEEDED(hr))
    {
        for (idx = 0; idx < nb_mon; idx++)
            CoTaskMemFree(regfilters[idx].Name);
        CoTaskMemFree(regfilters);
        IEnumMoniker_Release(ppEnumMoniker);
        return hr;
    }

    hr = IEnumRegFiltersImpl_Construct(regfilters, nb_mon, ppEnum);
    CoTaskMemFree(regfilters);
    IEnumMoniker_Release(ppEnumMoniker);
    
    return hr;
}


static HRESULT WINAPI FilterMapper_RegisterFilter(IFilterMapper * iface, CLSID clsid, LPCWSTR szName, DWORD dwMerit)
{
    HRESULT hr;
    LPWSTR wszClsid = NULL;
    HKEY hKey;
    LONG lRet;
    WCHAR wszKeyName[strlenW(wszFilterSlash) + (CHARS_IN_GUID-1) + 1];

    TRACE("(%p)->(%s, %s, %x)\n", iface, debugstr_guid(&clsid), debugstr_w(szName), dwMerit);

    hr = StringFromCLSID(&clsid, &wszClsid);

    if (SUCCEEDED(hr))
    {
        strcpyW(wszKeyName, wszFilterSlash);
        strcatW(wszKeyName, wszClsid);
    
        lRet = RegCreateKeyExW(HKEY_CLASSES_ROOT, wszKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
        hr = HRESULT_FROM_WIN32(lRet);
    }

    if (SUCCEEDED(hr))
    {
        lRet = RegSetValueExW(hKey, NULL, 0, REG_SZ, (const BYTE*)szName, strlenW(szName) + 1);
        hr = HRESULT_FROM_WIN32(lRet);
        CloseHandle(hKey);
    }

    if (SUCCEEDED(hr))
    {
        strcpyW(wszKeyName, wszClsidSlash);
        strcatW(wszKeyName, wszClsid);
    
        lRet = RegCreateKeyExW(HKEY_CLASSES_ROOT, wszKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
        hr = HRESULT_FROM_WIN32(lRet);
    }

    if (SUCCEEDED(hr))
    {
        lRet = RegSetValueExW(hKey, wszMeritName, 0, REG_DWORD, (LPBYTE)&dwMerit, sizeof(dwMerit));
        hr = HRESULT_FROM_WIN32(lRet);
        CloseHandle(hKey);
    }
    
    return hr;
}

static HRESULT WINAPI FilterMapper_RegisterFilterInstance(IFilterMapper * iface, CLSID clsid, LPCWSTR szName, CLSID *MRId)
{
    TRACE("(%p)->(%s, %s, %p)\n", iface, debugstr_guid(&clsid), debugstr_w(szName), MRId);

    /* Not implemented in Windows (tested on Win2k) */

    return E_NOTIMPL;
}

static HRESULT WINAPI FilterMapper_RegisterPin(
    IFilterMapper * iface,
    CLSID Filter,
    LPCWSTR szName,
    BOOL bRendered,
    BOOL bOutput,
    BOOL bZero,
    BOOL bMany,
    CLSID ConnectsToFilter,
    LPCWSTR ConnectsToPin)
{
    HRESULT hr;
    LONG lRet;
    LPWSTR wszClsid = NULL;
    HKEY hKey = NULL;
    HKEY hPinsKey = NULL;
    WCHAR * wszPinsKeyName;
    WCHAR wszKeyName[strlenW(wszClsidSlash) + (CHARS_IN_GUID-1) + 1];

    TRACE("(%p)->(%s, %s, %d, %d, %d, %d, %s, %s)\n", iface, debugstr_guid(&Filter), debugstr_w(szName), bRendered,
                bOutput, bZero, bMany, debugstr_guid(&ConnectsToFilter), debugstr_w(ConnectsToPin));

    hr = StringFromCLSID(&Filter, &wszClsid);

    if (SUCCEEDED(hr))
    {
        strcpyW(wszKeyName, wszClsidSlash);
        strcatW(wszKeyName, wszClsid);

        lRet = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszKeyName, 0, KEY_WRITE, &hKey);
        hr = HRESULT_FROM_WIN32(lRet);
    }

    if (SUCCEEDED(hr))
    {
        wszPinsKeyName = CoTaskMemAlloc((strlenW(wszPins) + 1 + strlenW(szName) + 1) * 2);
        if (!wszPinsKeyName)
             hr = E_OUTOFMEMORY;
    }

    if (SUCCEEDED(hr))
    {
        strcpyW(wszPinsKeyName, wszPins);
        strcatW(wszPinsKeyName, wszSlash);
        strcatW(wszPinsKeyName, szName);
    
        lRet = RegCreateKeyExW(hKey, wszPinsKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hPinsKey, NULL);
        hr = HRESULT_FROM_WIN32(lRet);
        CoTaskMemFree(wszPinsKeyName);
    }

    if (SUCCEEDED(hr))
    {
        lRet = RegSetValueExW(hPinsKey, wszAllowedMany, 0, REG_DWORD, (LPBYTE)&bMany, sizeof(bMany));
        hr = HRESULT_FROM_WIN32(lRet);
    }

    if (SUCCEEDED(hr))
    {
        lRet = RegSetValueExW(hPinsKey, wszAllowedZero, 0, REG_DWORD, (LPBYTE)&bZero, sizeof(bZero));
        hr = HRESULT_FROM_WIN32(lRet);
    }

    if (SUCCEEDED(hr))
    {
        lRet = RegSetValueExW(hPinsKey, wszDirection, 0, REG_DWORD, (LPBYTE)&bOutput, sizeof(bOutput));
        hr = HRESULT_FROM_WIN32(lRet);
    }

    if (SUCCEEDED(hr))
    {
        lRet = RegSetValueExW(hPinsKey, wszIsRendered, 0, REG_DWORD, (LPBYTE)&bRendered, sizeof(bRendered));
        hr = HRESULT_FROM_WIN32(lRet);
    }

    if (SUCCEEDED(hr))
    {
        lRet = RegCreateKeyExW(hPinsKey, wszTypes, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, NULL, NULL);
        hr = HRESULT_FROM_WIN32(lRet);
    }

    CoTaskMemFree(wszClsid);
    if (hKey)
        CloseHandle(hKey);
    if (hPinsKey)
        CloseHandle(hPinsKey);

    return hr;
}


static HRESULT WINAPI FilterMapper_RegisterPinType(
    IFilterMapper * iface,
    CLSID clsFilter,
    LPCWSTR szName,
    CLSID clsMajorType,
    CLSID clsSubType)
{
    HRESULT hr;
    LONG lRet;
    LPWSTR wszClsid = NULL;
    LPWSTR wszClsidMajorType = NULL;
    LPWSTR wszClsidSubType = NULL;
    HKEY hKey = NULL;
    WCHAR * wszTypesKey;
    WCHAR wszKeyName[strlenW(wszClsidSlash) + (CHARS_IN_GUID-1) + 1];

    TRACE("(%p)->(%s, %s, %s, %s)\n", iface, debugstr_guid(&clsFilter), debugstr_w(szName),
                    debugstr_guid(&clsMajorType), debugstr_guid(&clsSubType));

    hr = StringFromCLSID(&clsFilter, &wszClsid);

    if (SUCCEEDED(hr))
    {
        hr = StringFromCLSID(&clsMajorType, &wszClsidMajorType);
    }

    if (SUCCEEDED(hr))
    {
        hr = StringFromCLSID(&clsSubType, &wszClsidSubType);
    }

    if (SUCCEEDED(hr))
    {
        wszTypesKey = CoTaskMemAlloc((strlenW(wszClsidSlash) + strlenW(wszClsid) + strlenW(wszPins) +
                        strlenW(szName) + strlenW(wszTypes) + 3 + 1) * 2);
        if (!wszTypesKey)
            hr = E_OUTOFMEMORY;
    }

    if (SUCCEEDED(hr))
    {
        strcpyW(wszTypesKey, wszClsidSlash);
        strcatW(wszTypesKey, wszClsid);
        strcatW(wszTypesKey, wszSlash);
        strcatW(wszTypesKey, wszPins);
        strcatW(wszTypesKey, wszSlash);
        strcatW(wszTypesKey, szName);
        strcatW(wszTypesKey, wszSlash);
        strcatW(wszTypesKey, wszTypes);

        lRet = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszTypesKey, 0, KEY_WRITE, &hKey);
        hr = HRESULT_FROM_WIN32(lRet);
        CoTaskMemFree(wszTypesKey);
    }

    if (SUCCEEDED(hr))
    {
        strcpyW(wszKeyName, wszClsidMajorType);
        strcatW(wszKeyName, wszSlash);
        strcatW(wszKeyName, wszClsidSubType);

        lRet = RegCreateKeyExW(hKey, wszKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, NULL, NULL);
        hr = HRESULT_FROM_WIN32(lRet);
        CloseHandle(hKey);
    }

    CoTaskMemFree(wszClsid);
    CoTaskMemFree(wszClsidMajorType);
    CoTaskMemFree(wszClsidSubType);

    return hr;
}

static HRESULT WINAPI FilterMapper_UnregisterFilter(IFilterMapper * iface, CLSID Filter)
{
    HRESULT hr;
    LONG lRet;
    LPWSTR wszClsid = NULL;
    HKEY hKey;
    WCHAR wszKeyName[strlenW(wszClsidSlash) + (CHARS_IN_GUID-1) + 1];

    TRACE("(%p)->(%s)\n", iface, debugstr_guid(&Filter));

    hr = StringFromCLSID(&Filter, &wszClsid);

    if (SUCCEEDED(hr))
    {
        lRet = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszFilter, 0, KEY_WRITE, &hKey);
        hr = HRESULT_FROM_WIN32(lRet);
    }

    if (SUCCEEDED(hr))
    {
        lRet = RegDeleteKeyW(hKey, wszClsid);
        hr = HRESULT_FROM_WIN32(lRet);
        CloseHandle(hKey);
    }

    if (SUCCEEDED(hr))
    {
        strcpyW(wszKeyName, wszClsidSlash);
        strcatW(wszKeyName, wszClsid);

        lRet = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszKeyName, 0, KEY_WRITE, &hKey);
        hr = HRESULT_FROM_WIN32(lRet);
    }

    if (SUCCEEDED(hr))
    {
        lRet = RegDeleteKeyW(hKey, wszMeritName);
        hr = HRESULT_FROM_WIN32(lRet);
        CloseHandle(hKey);
    }

    CoTaskMemFree(wszClsid);

    return hr;
}

static HRESULT WINAPI FilterMapper_UnregisterFilterInstance(IFilterMapper * iface, CLSID MRId)
{
    TRACE("(%p)->(%s)\n", iface, debugstr_guid(&MRId));

    /* Not implemented in Windows (tested on Win2k) */

    return E_NOTIMPL;
}

static HRESULT WINAPI FilterMapper_UnregisterPin(IFilterMapper * iface, CLSID Filter, LPCWSTR Name)
{
    HRESULT hr;
    LONG lRet;
    LPWSTR wszClsid = NULL;
    HKEY hKey = NULL;
    WCHAR * wszPinNameKey;
    WCHAR wszKeyName[strlenW(wszClsidSlash) + (CHARS_IN_GUID-1) + 1];

    TRACE("(%p)->(%s, %s)\n", iface, debugstr_guid(&Filter), debugstr_w(Name));

    if (!Name)
        return E_INVALIDARG;

    hr = StringFromCLSID(&Filter, &wszClsid);

    if (SUCCEEDED(hr))
    {
        strcpyW(wszKeyName, wszClsidSlash);
        strcatW(wszKeyName, wszClsid);

        lRet = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszKeyName, 0, KEY_WRITE, &hKey);
        hr = HRESULT_FROM_WIN32(lRet);
    }

    if (SUCCEEDED(hr))
    {
        wszPinNameKey = CoTaskMemAlloc((strlenW(wszPins) + 1 + strlenW(Name) + 1) * 2);
        if (!wszPinNameKey)
            hr = E_OUTOFMEMORY;
    }

    if (SUCCEEDED(hr))
    {
        strcpyW(wszPinNameKey, wszPins);
        strcatW(wszPinNameKey, wszSlash);
        strcatW(wszPinNameKey, Name);

        lRet = RegDeleteKeyW(hKey, wszPinNameKey);
        hr = HRESULT_FROM_WIN32(lRet);
        CoTaskMemFree(wszPinNameKey);
    }

    CoTaskMemFree(wszClsid);
    if (hKey)
        CloseHandle(hKey);

    return hr;
}

static const IFilterMapperVtbl fmvtbl =
{

    FilterMapper_QueryInterface,
    FilterMapper_AddRef,
    FilterMapper_Release,

    FilterMapper_RegisterFilter,
    FilterMapper_RegisterFilterInstance,
    FilterMapper_RegisterPin,
    FilterMapper_RegisterPinType,
    FilterMapper_UnregisterFilter,
    FilterMapper_UnregisterFilterInstance,
    FilterMapper_UnregisterPin,
    FilterMapper_EnumMatchingFilters
};


/*** IUnknown methods ***/
static HRESULT WINAPI AMFilterData_QueryInterface(IAMFilterData * iface, REFIID riid, LPVOID *ppv)
{
    FilterMapper2Impl *This = impl_from_IAMFilterData(iface);

    return FilterMapper2_QueryInterface((IFilterMapper2*)This, riid, ppv);
}

static ULONG WINAPI AMFilterData_AddRef(IAMFilterData * iface)
{
    FilterMapper2Impl *This = impl_from_IAMFilterData(iface);

    return FilterMapper2_AddRef((IFilterMapper2*)This);
}

static ULONG WINAPI AMFilterData_Release(IAMFilterData * iface)
{
    FilterMapper2Impl *This = impl_from_IAMFilterData(iface);

    return FilterMapper2_Release((IFilterMapper2*)This);
}

/*** IAMFilterData methods ***/
static HRESULT WINAPI AMFilterData_ParseFilterData(IAMFilterData* iface,
                                                   BYTE *pData, ULONG cb,
                                                   BYTE **ppRegFilter2)
{
    FilterMapper2Impl *This = impl_from_IAMFilterData(iface);
    HRESULT hr = S_OK;
    REGFILTER2 *prf2;

    TRACE("(%p/%p)->(%p, %d, %p)\n", This, iface, pData, cb, ppRegFilter2);

    prf2 = CoTaskMemAlloc(sizeof(*prf2));
    if (!prf2)
        return E_OUTOFMEMORY;
    *ppRegFilter2 = (BYTE *)&prf2;

    hr = FM2_ReadFilterData(pData, prf2);
    if (FAILED(hr))
    {
        CoTaskMemFree(prf2);
        *ppRegFilter2 = NULL;
    }

    return hr;
}

static HRESULT WINAPI AMFilterData_CreateFilterData(IAMFilterData* iface,
                                                    REGFILTER2 *prf2,
                                                    BYTE **pRegFilterData,
                                                    ULONG *pcb)
{
    FilterMapper2Impl *This = impl_from_IAMFilterData(iface);

    TRACE("(%p/%p)->(%p, %p, %p)\n", This, iface, prf2, pRegFilterData, pcb);

    return FM2_WriteFilterData(prf2, pRegFilterData, pcb);
}

static const IAMFilterDataVtbl AMFilterDataVtbl = {
    AMFilterData_QueryInterface,
    AMFilterData_AddRef,
    AMFilterData_Release,
    AMFilterData_ParseFilterData,
    AMFilterData_CreateFilterData
};
