/*
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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"

#define COM_NO_WINDOWS_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);

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

static const IFilterMapper2Vtbl fm2vtbl;
static const IFilterMapperVtbl fmvtbl;

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

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)
{
    if (v->pData)
        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->refCount = 1;

    *ppObj = pFM2impl;

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

    return S_OK;
}

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

    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)->()\n", iface);

    return refCount;
}

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

    TRACE("(%p)->()\n", iface);

    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;
    HRESULT hr;

    TRACE("(%s, %lx, %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);

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

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

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

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

    CloseHandle(hKey);

    if (wClsidCategory)
        CoTaskMemFree(wClsidCategory);
    if (wClsidAMCat)
        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))
    {
        hr = HRESULT_FROM_WIN32(RegDeleteKeyW(HKEY_CLASSES_ROOT, wszKeyName));
    }

    if (wClsidCategory)
        CoTaskMemFree(wClsidCategory);
    if (wFilter)
        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);
    }
    if (wszClsid)
        CoTaskMemFree(wszClsid);
    return hr;
}

static HRESULT FM2_WriteFilterData(IPropertyBag * pPropBag, const REGFILTER2 * prf2)
{
    VARIANT var;
    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;
    SAFEARRAY * psa;
    SAFEARRAYBOUND saBound;
    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));
        }
    }

    saBound.lLbound = 0;
    saBound.cElements = mainStore.current + clsidStore.current;
    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, mainStore.pData, mainStore.current);
            memcpy(pbSAData + mainStore.current, clsidStore.pData, clsidStore.current);
            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);

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

static HRESULT FM2_ReadFilterData(IPropertyBag * pPropBag, REGFILTER2 * prf2)
{
    VARIANT var;
    HRESULT hr;
    LPBYTE pData = NULL;
    struct REG_RF * prrf;
    LPBYTE pCurrent;
    DWORD i;
    REGFILTERPINS2 * rgPins2;

    VariantInit(&var);
    V_VT(&var) = VT_ARRAY | VT_UI1;

    hr = IPropertyBag_Read(pPropBag, wszFilterDataName, &var, NULL);

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

    if (SUCCEEDED(hr))
    {
        prrf = (struct REG_RF *)pData;
        pCurrent = pData;

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

    if (SUCCEEDED(hr))
    {
        TRACE("version = %ld, merit = %lx, #pins = %ld, unused = %lx\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[%ld]: flags = %lx, instances = %ld, media types = %ld, mediums = %ld\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);
            }
        }

    }

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

    VariantClear(&var);

    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
        {
            if (szClsidTemp)
            {
                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))
        hr = FM2_WriteFilterData(pPropBag, &regfilter2);

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

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

    if (pregfp2)
        CoTaskMemFree(pregfp2);

    TRACE("-- returning %lx\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, %lx, %s, %lx, %s, %ld, %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 = %lx 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;
                    REGFILTER2 rf2;
                    DWORD i;
                    BOOL bInputMatch = !bInputNeeded;
                    BOOL bOutputMatch = !bOutputNeeded;

                    ZeroMemory(&rf2, sizeof(rf2));

                    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 = FM2_ReadFilterData(pPropBag, &rf2);

                    /* 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, %lx, %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;
    WCHAR wszKeyName[strlenW(wszFilterSlash) + (CHARS_IN_GUID-1) + 1];

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

    hr = StringFromCLSID(&clsid, &wszClsid);

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

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

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

    if (SUCCEEDED(hr))
    {
        hr = HRESULT_FROM_WIN32(RegSetValueExW(hKey, wszMeritName, 0, REG_DWORD, (LPBYTE)&dwMerit, sizeof(dwMerit)));
        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;
    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);

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

    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);
    
        hr = HRESULT_FROM_WIN32(RegCreateKeyExW(hKey, wszPinsKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hPinsKey, NULL));
        CoTaskMemFree(wszPinsKeyName);
    }

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

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

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

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

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

    if (wszClsid)
        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;
    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);

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

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

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

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

    return hr;
}

static HRESULT WINAPI FilterMapper_UnregisterFilter(IFilterMapper * iface, CLSID Filter)
{
    HRESULT hr;
    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))
    {
        hr = HRESULT_FROM_WIN32(RegOpenKeyExW(HKEY_CLASSES_ROOT, wszFilter, 0, KEY_WRITE, &hKey));
    }

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

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

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

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

    if (wszClsid)
        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;
    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);

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

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

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

    if (wszClsid)
        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
};
