From 57b2104f54dd4632c8cc194795238ae400b6cf7a Mon Sep 17 00:00:00 2001 From: Christian Costa Date: Mon, 1 Mar 2004 23:32:04 +0000 Subject: [PATCH] Implemented IFilterMapper and IEnumRegFilters interfaces. Fixed IFilterMapper2_EnumMatchingFilters. --- dlls/quartz/Makefile.in | 1 + dlls/quartz/enumregfilters.c | 212 ++++++++++++++++++++++ dlls/quartz/filtermapper.c | 424 +++++++++++++++++++++++++++++++++++++++++-- dlls/quartz/quartz_private.h | 1 + 4 files changed, 620 insertions(+), 18 deletions(-) create mode 100644 dlls/quartz/enumregfilters.c diff --git a/dlls/quartz/Makefile.in b/dlls/quartz/Makefile.in index 3da07ce86cb..39cddfb1803 100644 --- a/dlls/quartz/Makefile.in +++ b/dlls/quartz/Makefile.in @@ -12,6 +12,7 @@ C_SRCS = \ enummedia.c \ enummoniker.c \ enumpins.c \ + enumregfilters.c \ filesource.c \ filtergraph.c \ filtermapper.c \ diff --git a/dlls/quartz/enumregfilters.c b/dlls/quartz/enumregfilters.c new file mode 100644 index 00000000000..178fe29795f --- /dev/null +++ b/dlls/quartz/enumregfilters.c @@ -0,0 +1,212 @@ +/* + * Implementation of IEnumRegFilters Interface + * + * 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 + */ + +#include "quartz_private.h" + +#include "wine/unicode.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(quartz); + +typedef struct IEnumRegFiltersImpl +{ + const IEnumRegFiltersVtbl * lpVtbl; + ULONG refCount; + ULONG size; + REGFILTER* RegFilters; + ULONG uIndex; +} IEnumRegFiltersImpl; + +static const struct IEnumRegFiltersVtbl IEnumRegFiltersImpl_Vtbl; + +HRESULT IEnumRegFiltersImpl_Create(REGFILTER* pInRegFilters, const ULONG size, IEnumRegFilters ** ppEnum) +{ + IEnumRegFiltersImpl* pEnumRegFilters; + REGFILTER* pRegFilters = NULL; + int i; + + TRACE("(%p, %ld, %p)\n", pInRegFilters, size, ppEnum); + + pEnumRegFilters = CoTaskMemAlloc(sizeof(IEnumRegFiltersImpl)); + if (!pEnumRegFilters) + { + *ppEnum = NULL; + return E_OUTOFMEMORY; + } + + /* Accept size of 0 */ + if (size) + { + pRegFilters = CoTaskMemAlloc(sizeof(REGFILTER)*size); + if (!pRegFilters) + { + CoTaskMemFree(pEnumRegFilters); + *ppEnum = NULL; + return E_OUTOFMEMORY; + } + } + + for(i = 0; i < size; i++) + { + pRegFilters[i].Clsid = pInRegFilters[i].Clsid; + pRegFilters[i].Name = (WCHAR*)CoTaskMemAlloc((strlenW(pInRegFilters[i].Name)+1)*sizeof(WCHAR)); + if (!pRegFilters[i].Name) + { + while(i) + CoTaskMemFree(pRegFilters[--i].Name); + CoTaskMemFree(pRegFilters); + CoTaskMemFree(pEnumRegFilters); + return E_OUTOFMEMORY; + } + CopyMemory(pRegFilters[i].Name, pInRegFilters[i].Name, (strlenW(pInRegFilters[i].Name)+1)*sizeof(WCHAR)); + } + + pEnumRegFilters->lpVtbl = &IEnumRegFiltersImpl_Vtbl; + pEnumRegFilters->refCount = 1; + pEnumRegFilters->uIndex = 0; + pEnumRegFilters->RegFilters = pRegFilters; + pEnumRegFilters->size = size; + + *ppEnum = (IEnumRegFilters *)(&pEnumRegFilters->lpVtbl); + + return S_OK; +} + +static HRESULT WINAPI IEnumRegFiltersImpl_QueryInterface(IEnumRegFilters * iface, REFIID riid, LPVOID * ppv) +{ + TRACE("(%p)->(%s, %p)\n", iface, qzdebugstr_guid(riid), ppv); + + *ppv = NULL; + + if (IsEqualIID(riid, &IID_IUnknown)) + *ppv = (LPVOID)iface; + else if (IsEqualIID(riid, &IID_IEnumRegFilters)) + *ppv = (LPVOID)iface; + + if (*ppv) + { + IUnknown_AddRef((IUnknown *)(*ppv)); + return S_OK; + } + + FIXME("No interface for %s!\n", qzdebugstr_guid(riid)); + + return E_NOINTERFACE; +} + +static ULONG WINAPI IEnumRegFiltersImpl_AddRef(IEnumRegFilters * iface) +{ + ICOM_THIS(IEnumRegFiltersImpl, iface); + + TRACE("(%p)\n", iface); + + return ++This->refCount; +} + +static ULONG WINAPI IEnumRegFiltersImpl_Release(IEnumRegFilters * iface) +{ + ICOM_THIS(IEnumRegFiltersImpl, iface); + + TRACE("(%p)\n", iface); + + if (!--This->refCount) + { + CoTaskMemFree(This); + return 0; + } else + return This->refCount; +} + +static HRESULT WINAPI IEnumRegFiltersImpl_Next(IEnumRegFilters * iface, ULONG cFilters, REGFILTER ** ppRegFilter, ULONG * pcFetched) +{ + ULONG cFetched; + ICOM_THIS(IEnumRegFiltersImpl, iface); + int i; + + cFetched = min(This->size, This->uIndex + cFilters) - This->uIndex; + + TRACE("(%p)->(%lu, %p, %p)\n", iface, cFilters, ppRegFilter, pcFetched); + + if (cFetched > 0) + { + for(i = 0; i < cFetched; i++) + { + /* The string in the REGFILTER structure must be allocated in the same block as the REGFILTER structure itself */ + ppRegFilter[i] = (REGFILTER*)CoTaskMemAlloc(sizeof(REGFILTER)+(strlenW(This->RegFilters[i].Name)+1)*sizeof(WCHAR)); + if (!ppRegFilter[i]) + { + while(i) + { + CoTaskMemFree(ppRegFilter[--i]); + ppRegFilter[i] = NULL; + } + return E_OUTOFMEMORY; + } + ppRegFilter[i]->Clsid = This->RegFilters[i].Clsid; + ppRegFilter[i]->Name = (WCHAR*)((char*)ppRegFilter[i]+sizeof(REGFILTER)); + CopyMemory(ppRegFilter[i]->Name, This->RegFilters[i].Name, (strlenW(This->RegFilters[i].Name)+1)*sizeof(WCHAR)); + } + + This->uIndex += cFetched; + if (pcFetched) + *pcFetched = cFetched; + return S_OK; + } + + return S_FALSE; +} + +static HRESULT WINAPI IEnumRegFiltersImpl_Skip(IEnumRegFilters * iface, ULONG n) +{ + TRACE("(%p)->(%lu)\n", iface, n); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IEnumRegFiltersImpl_Reset(IEnumRegFilters * iface) +{ + ICOM_THIS(IEnumRegFiltersImpl, iface); + + TRACE("(%p)\n", iface); + + This->uIndex = 0; + return S_OK; +} + +static HRESULT WINAPI IEnumRegFiltersImpl_Clone(IEnumRegFilters * iface, IEnumRegFilters ** ppEnum) +{ + TRACE("(%p)->(%p)\n", iface, ppEnum); + + return E_NOTIMPL; +} + +static const IEnumRegFiltersVtbl IEnumRegFiltersImpl_Vtbl = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + IEnumRegFiltersImpl_QueryInterface, + IEnumRegFiltersImpl_AddRef, + IEnumRegFiltersImpl_Release, + IEnumRegFiltersImpl_Next, + IEnumRegFiltersImpl_Skip, + IEnumRegFiltersImpl_Reset, + IEnumRegFiltersImpl_Clone +}; + diff --git a/dlls/quartz/filtermapper.c b/dlls/quartz/filtermapper.c index cd2b8141f6b..586e99adb92 100644 --- a/dlls/quartz/filtermapper.c +++ b/dlls/quartz/filtermapper.c @@ -2,6 +2,7 @@ * 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 @@ -56,6 +57,7 @@ static struct ICOM_VTABLE(IFilterMapper) fmvtbl; 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}; @@ -65,6 +67,18 @@ static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a', 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 @@ -197,7 +211,7 @@ static ULONG WINAPI FilterMapper2_AddRef(IFilterMapper2 * iface) { ICOM_THIS(FilterMapper2Impl, iface); - TRACE("()\n"); + TRACE("(%p)->()\n", iface); return InterlockedIncrement(&This->refCount); } @@ -206,7 +220,7 @@ static ULONG WINAPI FilterMapper2_Release(IFilterMapper2 * iface) { ICOM_THIS(FilterMapper2Impl, iface); - TRACE("()\n"); + TRACE("(%p)->()\n", iface); if (InterlockedDecrement(&This->refCount) == 0) { @@ -879,7 +893,7 @@ static HRESULT WINAPI FilterMapper2_EnumMatchingFilters( if (SUCCEEDED(hrSub)) hrSub = ICreateDevEnum_CreateClassEnumerator(pCreateDevEnum, &clsidCat, &pEnum, 0); - if (SUCCEEDED(hrSub)) + if (hrSub == S_OK) { while (IEnumMoniker_Next(pEnum, 1, &pMoniker, NULL) == S_OK) { @@ -941,7 +955,6 @@ static HRESULT WINAPI FilterMapper2_EnumMatchingFilters( IMoniker_Release(pMonikerCat); } - if (SUCCEEDED(hr)) { IMoniker ** ppMoniker; @@ -1024,20 +1037,183 @@ static HRESULT WINAPI FilterMapper_EnumMatchingFilters( CLSID clsOutMaj, CLSID clsOutSub) { - FIXME("stub\n"); - return E_NOTIMPL; + ICOM_THIS_From_IFilterMapper(FilterMapper2Impl, 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_Create(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)) + { + 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_Create(regfilters, nb_mon, ppEnum); + CoTaskMemFree(regfilters); + IEnumMoniker_Release(ppEnumMoniker); + + return hr; } static HRESULT WINAPI FilterMapper_RegisterFilter(IFilterMapper * iface, CLSID clsid, LPCWSTR szName, DWORD dwMerit) { - FIXME("stub\n"); - return E_NOTIMPL; + 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, (LPBYTE)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) { - FIXME("stub\n"); + TRACE("(%p)->(%s, %s, %p)\n", iface, debugstr_guid(&clsid), debugstr_w(szName), MRId); + + /* Not implemented in Windows (tested on Win2k) */ + return E_NOTIMPL; } @@ -1052,8 +1228,76 @@ static HRESULT WINAPI FilterMapper_RegisterPin( CLSID ConnectsToFilter, LPCWSTR ConnectsToPin) { - FIXME("stub\n"); - return E_NOTIMPL; + 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; } @@ -1064,26 +1308,169 @@ static HRESULT WINAPI FilterMapper_RegisterPinType( CLSID clsMajorType, CLSID clsSubType) { - FIXME("stub\n"); - return E_NOTIMPL; + 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) { - FIXME("stub\n"); - return E_NOTIMPL; + 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) { - FIXME("stub\n"); + 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) { - FIXME("stub\n"); - return E_NOTIMPL; + 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 ICOM_VTABLE(IFilterMapper) fmvtbl = @@ -1103,3 +1490,4 @@ static ICOM_VTABLE(IFilterMapper) fmvtbl = FilterMapper_UnregisterPin, FilterMapper_EnumMatchingFilters }; + diff --git a/dlls/quartz/quartz_private.h b/dlls/quartz/quartz_private.h index 93874e9eef9..a1b5dc9000b 100644 --- a/dlls/quartz/quartz_private.h +++ b/dlls/quartz/quartz_private.h @@ -59,6 +59,7 @@ typedef struct tagENUMEDIADETAILS HRESULT IEnumPinsImpl_Construct(const ENUMPINDETAILS * pDetails, IEnumPins ** ppEnum); HRESULT IEnumMediaTypesImpl_Construct(const ENUMMEDIADETAILS * pDetails, IEnumMediaTypes ** ppEnum); +HRESULT IEnumRegFiltersImpl_Create(REGFILTER* pInRegFilters, const ULONG size, IEnumRegFilters ** ppEnum); extern const char * qzdebugstr_guid(const GUID * id); extern const char * qzdebugstr_State(FILTER_STATE state); -- 2.11.4.GIT