/*
 * IFilterMapper & IFilterMapper3 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);

#define ARRAYSIZE(array) (sizeof(array)/sizeof((array)[0]))

/* 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;
};
static const GUID IID_IAMFilterData = {
 0x97f7c4d4, 0x547b, 0x4a5f, { 0x83,0x32, 0x53,0x64,0x30,0xad,0x2e,0x4d }
};


typedef struct FilterMapper3Impl
{
    const IFilterMapper3Vtbl *lpVtbl;
    const IFilterMapperVtbl  *lpVtblFilterMapper;
    const IAMFilterDataVtbl  *lpVtblAMFilterData;
    const IUnknownVtbl *IInner_vtbl;
    LONG refCount;
    IUnknown * pUnkOuter;
    BOOL bUnkOuterValid;
    BOOL bAggregatable;
} FilterMapper3Impl;

static const IUnknownVtbl IInner_VTable;
static const IFilterMapper3Vtbl fm3vtbl;
static const IFilterMapperVtbl fmvtbl;
static const IAMFilterDataVtbl AMFilterDataVtbl;

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

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

static inline FilterMapper3Impl *impl_from_inner_IUnknown( IUnknown *iface )
{
    return (FilterMapper3Impl *)((char*)iface - FIELD_OFFSET(FilterMapper3Impl, IInner_vtbl));
}

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(const 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)
{
    FilterMapper3Impl * pFM2impl;

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

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

    pFM2impl->pUnkOuter = pUnkOuter;
    pFM2impl->bUnkOuterValid = FALSE;
    pFM2impl->bAggregatable = FALSE;
    pFM2impl->IInner_vtbl = &IInner_VTable;
    pFM2impl->lpVtbl = &fm3vtbl;
    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)
{
    FilterMapper3Impl *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 (inner) methods ***/

static HRESULT WINAPI Inner_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv)
{
    FilterMapper3Impl *This = impl_from_inner_IUnknown(iface);
    TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);

    if (This->bAggregatable)
        This->bUnkOuterValid = TRUE;

    *ppv = NULL;

    if (IsEqualIID(riid, &IID_IUnknown))
        *ppv = &This->IInner_vtbl;
    else if (IsEqualIID(riid, &IID_IFilterMapper2) ||
        IsEqualIID(riid, &IID_IFilterMapper3))
        *ppv = This;
    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 Inner_AddRef(IUnknown * iface)
{
    FilterMapper3Impl *This = impl_from_inner_IUnknown(iface);
    ULONG refCount = InterlockedIncrement(&This->refCount);

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

    return refCount;
}

static ULONG WINAPI Inner_Release(IUnknown * iface)
{
    FilterMapper3Impl *This = impl_from_inner_IUnknown(iface);
    ULONG refCount = InterlockedDecrement(&This->refCount);

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

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

static const IUnknownVtbl IInner_VTable =
{
    Inner_QueryInterface,
    Inner_AddRef,
    Inner_Release
};

static HRESULT WINAPI FilterMapper3_QueryInterface(IFilterMapper3 * iface, REFIID riid, LPVOID *ppv)
{
    FilterMapper3Impl *This = (FilterMapper3Impl *)iface;

    if (This->bAggregatable)
        This->bUnkOuterValid = TRUE;

    if (This->pUnkOuter)
    {
        if (This->bAggregatable)
            return IUnknown_QueryInterface(This->pUnkOuter, riid, ppv);

        if (IsEqualIID(riid, &IID_IUnknown))
        {
            HRESULT hr;

            IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
            hr = IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv);
            IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
            This->bAggregatable = TRUE;
            return hr;
        }

        *ppv = NULL;
        return E_NOINTERFACE;
    }

    return IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv);
}

static ULONG WINAPI FilterMapper3_AddRef(IFilterMapper3 * iface)
{
    FilterMapper3Impl *This = (FilterMapper3Impl *)iface;

    if (This->pUnkOuter && This->bUnkOuterValid)
        return IUnknown_AddRef(This->pUnkOuter);
    return IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
}

static ULONG WINAPI FilterMapper3_Release(IFilterMapper3 * iface)
{
    FilterMapper3Impl *This = (FilterMapper3Impl *)iface;

    if (This->pUnkOuter && This->bUnkOuterValid)
        return IUnknown_Release(This->pUnkOuter);
    return IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
}

/*** IFilterMapper3 methods ***/

static HRESULT WINAPI FilterMapper3_CreateCategory(
    IFilterMapper3 * iface,
    REFCLSID clsidCategory,
    DWORD dwCategoryMerit,
    LPCWSTR szDescription)
{
    LPWSTR wClsidAMCat = NULL;
    LPWSTR wClsidCategory = NULL;
    WCHAR wszKeyName[ARRAYSIZE(wszClsidSlash)-1 + ARRAYSIZE(wszSlashInstance)-1 + (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 FilterMapper3_UnregisterFilter(
    IFilterMapper3 * 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;
    HRESULT ret;
    BSTR value;

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

    ret = IPropertyBag_Write(pPropBag, wszFriendlyName, &var);
    SysFreeString(value);

    return ret;
}

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;
            const CLSID * clsMinorType = rgPin2.lpMediaType[j].clsMinorType ? rgPin2.lpMediaType[j].clsMinorType : &MEDIASUBTYPE_NULL;
            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*)clsMinorType, sizeof(CLSID));
            if (rt.dwOffsetMinor == -1)
                rt.dwOffsetMinor = add_data(&clsidStore, (const BYTE*)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].lpMediaType);
        CoTaskMemFree((LPVOID)prf2->u.s1.rgPins2[i].lpMedium);
    }
    CoTaskMemFree((LPVOID)prf2->u.s1.rgPins2);
}

static HRESULT WINAPI FilterMapper3_RegisterFilter(
    IFilterMapper3 * 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 = 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);
    CoTaskMemFree(pwszParseName);

    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 = left;
    const struct MONIKER_MERIT * mmRight = 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 FilterMapper3_EnumMatchingFilters(
    IFilterMapper3 * 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 (FAILED(hr))
        return hr;

    hr = ICreateDevEnum_CreateClassEnumerator(pCreateDevEnum, &CLSID_ActiveMovieCategories, &pEnumCat, 0);
    if (FAILED(hr)) {
        ICreateDevEnum_Release(pCreateDevEnum);
        return hr;
    }

    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))
                    {
                        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 HRESULT WINAPI FilterMapper3_GetICreateDevEnum(IFilterMapper3 *iface, ICreateDevEnum **ppEnum)
{
    TRACE("(%p, %p)\n", iface, ppEnum);
    if (!ppEnum)
        return E_POINTER;
    return CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, &IID_ICreateDevEnum, (void**)ppEnum);
}

static const IFilterMapper3Vtbl fm3vtbl =
{

    FilterMapper3_QueryInterface,
    FilterMapper3_AddRef,
    FilterMapper3_Release,

    FilterMapper3_CreateCategory,
    FilterMapper3_UnregisterFilter,
    FilterMapper3_RegisterFilter,
    FilterMapper3_EnumMatchingFilters,
    FilterMapper3_GetICreateDevEnum
};

/*** IUnknown methods ***/

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

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

    return FilterMapper3_QueryInterface((IFilterMapper3*)&This->lpVtbl, riid, ppv);
}

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

    return FilterMapper3_AddRef((IFilterMapper3*)This);
}

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

    return FilterMapper3_Release((IFilterMapper3*)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)
{
    FilterMapper3Impl *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;

    *ppEnum = NULL;

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

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

    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;
    }
    ZeroMemory(regfilters, nb_mon * sizeof(REGFILTER)); /* will prevent bad free of Name in case of error. */
    
    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);

        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);

        VariantClear(&var);

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

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

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

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

    if (SUCCEEDED(hr))
    {
        hr = IEnumRegFiltersImpl_Construct(regfilters, nb_mon, ppEnum);
    }

    for (idx = 0; idx < nb_mon; idx++)
        CoTaskMemFree(regfilters[idx].Name);
    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[ARRAYSIZE(wszFilterSlash)-1 + (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) * sizeof(WCHAR));
        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);
    }
    
    CoTaskMemFree(wszClsid);

    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[ARRAYSIZE(wszClsidSlash)-1 + (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))
    {
        HKEY hkeyDummy = NULL;

        lRet = RegCreateKeyExW(hPinsKey, wszTypes, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkeyDummy, NULL);
        hr = HRESULT_FROM_WIN32(lRet);

        if (hkeyDummy) RegCloseKey(hkeyDummy);
    }

    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[MAX_PATH];

    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))
    {
        HKEY hkeyDummy = NULL;

        strcpyW(wszKeyName, wszClsidMajorType);
        strcatW(wszKeyName, wszSlash);
        strcatW(wszKeyName, wszClsidSubType);

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

        if (hkeyDummy) RegCloseKey(hkeyDummy);
    }

    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[ARRAYSIZE(wszClsidSlash)-1 + (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 = RegDeleteValueW(hKey, wszMeritName);
        if (lRet != ERROR_SUCCESS)
            hr = HRESULT_FROM_WIN32(lRet);

        lRet = RegDeleteTreeW(hKey, wszPins);
        if (lRet != ERROR_SUCCESS)
            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[ARRAYSIZE(wszClsidSlash)-1 + (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 = RegDeleteTreeW(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)
{
    FilterMapper3Impl *This = impl_from_IAMFilterData(iface);

    return FilterMapper3_QueryInterface((IFilterMapper3*)This, riid, ppv);
}

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

    return FilterMapper3_AddRef((IFilterMapper3*)This);
}

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

    return FilterMapper3_Release((IFilterMapper3*)This);
}

/*** IAMFilterData methods ***/
static HRESULT WINAPI AMFilterData_ParseFilterData(IAMFilterData* iface,
                                                   BYTE *pData, ULONG cb,
                                                   BYTE **ppRegFilter2)
{
    FilterMapper3Impl *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)
{
    FilterMapper3Impl *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
};
