/* * $Id$ * * (C) 2003-2006 Gabest * (C) 2006-2010 see AUTHORS * * This file is part of mplayerc. * * Mplayerc is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Mplayerc 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "stdafx.h" #include "FakeFilterMapper2.h" #include "MacrovisionKicker.h" #include "../../DSUtil/DSUtil.h" #include #include #include HRESULT (__stdcall * Real_CoCreateInstance)(CONST IID& a0, LPUNKNOWN a1, DWORD a2, CONST IID& a3, LPVOID* a4) = CoCreateInstance; LONG (WINAPI * Real_RegCreateKeyExA)(HKEY a0, LPCSTR a1, DWORD a2, LPSTR a3, DWORD a4, REGSAM a5, LPSECURITY_ATTRIBUTES a6, PHKEY a7, LPDWORD a8) = RegCreateKeyExA; LONG (WINAPI * Real_RegCreateKeyExW)(HKEY a0, LPCWSTR a1, DWORD a2, LPWSTR a3, DWORD a4, REGSAM a5, LPSECURITY_ATTRIBUTES a6, PHKEY a7, LPDWORD a8) = RegCreateKeyExW; LONG (WINAPI * Real_RegDeleteKeyA)(HKEY a0, LPCSTR a1) = RegDeleteKeyA; LONG (WINAPI * Real_RegDeleteKeyW)(HKEY a0, LPCWSTR a1) = RegDeleteKeyW; LONG (WINAPI * Real_RegDeleteValueA)(HKEY a0, LPCSTR a1) = RegDeleteValueA; LONG (WINAPI * Real_RegDeleteValueW)(HKEY a0, LPCWSTR a1) = RegDeleteValueW; LONG (WINAPI * Real_RegEnumKeyExA)(HKEY a0, DWORD a1, LPSTR a2, LPDWORD a3, LPDWORD a4, LPSTR a5, LPDWORD a6, struct _FILETIME* a7) = RegEnumKeyExA; LONG (WINAPI * Real_RegEnumKeyExW)(HKEY a0, DWORD a1, LPWSTR a2, LPDWORD a3, LPDWORD a4, LPWSTR a5, LPDWORD a6, struct _FILETIME* a7) = RegEnumKeyExW; LONG (WINAPI * Real_RegEnumValueA)(HKEY a0, DWORD a1, LPSTR a2, LPDWORD a3, LPDWORD a4, LPDWORD a5, LPBYTE a6, LPDWORD a7) = RegEnumValueA; LONG (WINAPI * Real_RegEnumValueW)(HKEY a0, DWORD a1, LPWSTR a2, LPDWORD a3, LPDWORD a4, LPDWORD a5, LPBYTE a6, LPDWORD a7) = RegEnumValueW; LONG (WINAPI * Real_RegOpenKeyExA)(HKEY a0, LPCSTR a1, DWORD a2, REGSAM a3, PHKEY a4) = RegOpenKeyExA; LONG (WINAPI * Real_RegOpenKeyExW)(HKEY a0, LPCWSTR a1, DWORD a2, REGSAM a3, PHKEY a4) = RegOpenKeyExW; LONG (WINAPI * Real_RegQueryInfoKeyA)(HKEY a0, LPSTR a1, LPDWORD a2, LPDWORD a3, LPDWORD a4, LPDWORD a5, LPDWORD a6, LPDWORD a7, LPDWORD a8, LPDWORD a9, LPDWORD a10, struct _FILETIME* a11) = RegQueryInfoKeyA; LONG (WINAPI * Real_RegQueryInfoKeyW)(HKEY a0, LPWSTR a1, LPDWORD a2, LPDWORD a3, LPDWORD a4, LPDWORD a5, LPDWORD a6, LPDWORD a7, LPDWORD a8, LPDWORD a9, LPDWORD a10, struct _FILETIME* a11) = RegQueryInfoKeyW; LONG (WINAPI * Real_RegQueryValueExA)(HKEY a0, LPCSTR a1, LPDWORD a2, LPDWORD a3, LPBYTE a4, LPDWORD a5) = RegQueryValueExA; LONG (WINAPI * Real_RegQueryValueExW)(HKEY a0, LPCWSTR a1, LPDWORD a2, LPDWORD a3, LPBYTE a4, LPDWORD a5) = RegQueryValueExW; LONG (WINAPI * Real_RegSetValueExA)(HKEY a0, LPCSTR a1, DWORD a2, DWORD a3, const BYTE* a4, DWORD a5) = RegSetValueExA; LONG (WINAPI * Real_RegSetValueExW)(HKEY a0, LPCWSTR a1, DWORD a2, DWORD a3, const BYTE* a4, DWORD a5) = RegSetValueExW; LONG (WINAPI * Real_RegCloseKey)(HKEY a0) = RegCloseKey; LONG (WINAPI * Real_RegFlushKey)(HKEY a0) = RegFlushKey; LONG (WINAPI * Real_RegCreateKeyA)(HKEY a0, LPCSTR a1, PHKEY a2) = RegCreateKeyA; LONG (WINAPI * Real_RegCreateKeyW)(HKEY a0, LPCWSTR a1, PHKEY a2) = RegCreateKeyW; LONG (WINAPI * Real_RegOpenKeyA)(HKEY a0, LPCSTR a1, PHKEY a2) = RegOpenKeyA; LONG (WINAPI * Real_RegOpenKeyW)(HKEY a0, LPCWSTR a1, PHKEY a2) = RegOpenKeyW; LONG (WINAPI * Real_RegQueryValueA)(HKEY a0, LPCSTR a1, LPSTR a2, PLONG a3) = RegQueryValueA; LONG (WINAPI * Real_RegQueryValueW)(HKEY a0, LPCWSTR a1, LPWSTR a2, PLONG a3) = RegQueryValueW; LONG (WINAPI * Real_RegSetValueW)(HKEY a0, LPCWSTR a1, DWORD a2, LPCWSTR a3, DWORD a4) = RegSetValueW; LONG (WINAPI * Real_RegSetValueA)(HKEY a0, LPCSTR a1, DWORD a2, LPCSTR a3, DWORD a4) = RegSetValueA; HRESULT WINAPI Mine_CoCreateInstance(IN REFCLSID rclsid, IN LPUNKNOWN pUnkOuter, IN DWORD dwClsContext, IN REFIID riid, OUT LPVOID FAR* ppv) { if(CFilterMapper2::m_pFilterMapper2) { CheckPointer(ppv, E_POINTER); if(rclsid == CLSID_FilterMapper) { ASSERT(0); return REGDB_E_CLASSNOTREG; // sorry... } if(rclsid == CLSID_FilterMapper2) { if(pUnkOuter) return CLASS_E_NOAGGREGATION; if(riid == __uuidof(IUnknown)) { CFilterMapper2::m_pFilterMapper2->AddRef(); *ppv = (IUnknown*)CFilterMapper2::m_pFilterMapper2; return S_OK; } else if(riid == __uuidof(IFilterMapper2)) { CFilterMapper2::m_pFilterMapper2->AddRef(); *ppv = (IFilterMapper2*)CFilterMapper2::m_pFilterMapper2; return S_OK; } else { return E_NOINTERFACE; } } } /* else { if(rclsid == CLSID_FilterMapper2) { CFilterMapper2* pFM2 = DNew CFilterMapper2(true, false, pUnkOuter); CComPtr pUnk = (IUnknown*)pFM2; return pUnk->QueryInterface(riid, ppv); } } */ if(!pUnkOuter) if(rclsid == CLSID_VideoMixingRenderer || rclsid == CLSID_VideoMixingRenderer9 || rclsid == CLSID_VideoRenderer || rclsid == CLSID_VideoRendererDefault || rclsid == CLSID_OverlayMixer)// || rclsid == CLSID_OverlayMixer2 - where is this declared?) { CMacrovisionKicker* pMK = DNew CMacrovisionKicker(NAME("CMacrovisionKicker"), NULL); CComPtr pUnk = (IUnknown*)(INonDelegatingUnknown*)pMK; CComPtr pInner; HRESULT hr; if(SUCCEEDED(hr = Real_CoCreateInstance(rclsid, pUnk, dwClsContext, __uuidof(IUnknown), (void**)&pInner))) { pMK->SetInner(pInner); return pUnk->QueryInterface(riid, ppv); } } return Real_CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv); } #define FAKEHKEY (HKEY)0x12345678 LONG WINAPI Mine_RegCloseKey(HKEY a0) { if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) { return ERROR_SUCCESS; } return Real_RegCloseKey(a0); } LONG WINAPI Mine_RegFlushKey(HKEY a0) { if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) { return ERROR_SUCCESS; } return Real_RegFlushKey(a0); } LONG WINAPI Mine_RegCreateKeyA(HKEY a0, LPCSTR a1, PHKEY a2) { if(CFilterMapper2::m_pFilterMapper2) { *a2 = FAKEHKEY; return ERROR_SUCCESS; } return Real_RegCreateKeyA(a0, a1, a2); } LONG WINAPI Mine_RegCreateKeyW(HKEY a0, LPCWSTR a1, PHKEY a2) { if(CFilterMapper2::m_pFilterMapper2) { *a2 = FAKEHKEY; return ERROR_SUCCESS; } return Real_RegCreateKeyW(a0, a1, a2); } LONG WINAPI Mine_RegCreateKeyExA(HKEY a0, LPCSTR a1, DWORD a2, LPSTR a3, DWORD a4, REGSAM a5, LPSECURITY_ATTRIBUTES a6, PHKEY a7, LPDWORD a8) { if(CFilterMapper2::m_pFilterMapper2) { *a7 = FAKEHKEY; return ERROR_SUCCESS; } return Real_RegCreateKeyExA(a0, a1, a2, a3, a4, a5, a6, a7, a8); } LONG WINAPI Mine_RegCreateKeyExW(HKEY a0, LPCWSTR a1, DWORD a2, LPWSTR a3, DWORD a4, REGSAM a5, LPSECURITY_ATTRIBUTES a6, PHKEY a7, LPDWORD a8) { if(CFilterMapper2::m_pFilterMapper2) { *a7 = FAKEHKEY; return ERROR_SUCCESS; } return Real_RegCreateKeyExW(a0, a1, a2, a3, a4, a5, a6, a7, a8); } LONG WINAPI Mine_RegDeleteKeyA(HKEY a0, LPCSTR a1) { if(CFilterMapper2::m_pFilterMapper2 && (a0 == FAKEHKEY || (int)a0 < 0)) { return ERROR_SUCCESS; } return Real_RegDeleteKeyA(a0, a1); } LONG WINAPI Mine_RegDeleteKeyW(HKEY a0, LPCWSTR a1) { if(CFilterMapper2::m_pFilterMapper2 && (a0 == FAKEHKEY || (int)a0 < 0)) { return ERROR_SUCCESS; } return Real_RegDeleteKeyW(a0, a1); } LONG WINAPI Mine_RegDeleteValueA(HKEY a0, LPCSTR a1) { if(CFilterMapper2::m_pFilterMapper2 && (a0 == FAKEHKEY || (int)a0 < 0)) { return ERROR_SUCCESS; } return Real_RegDeleteValueA(a0, a1); } LONG WINAPI Mine_RegDeleteValueW(HKEY a0, LPCWSTR a1) { if(CFilterMapper2::m_pFilterMapper2 && (a0 == FAKEHKEY || (int)a0 < 0)) { return ERROR_SUCCESS; } return Real_RegDeleteValueW(a0, a1); } LONG WINAPI Mine_RegEnumKeyExA(HKEY a0, DWORD a1, LPSTR a2, LPDWORD a3, LPDWORD a4, LPSTR a5, LPDWORD a6, struct _FILETIME* a7) { if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) { return ERROR_NO_MORE_ITEMS; } return Real_RegEnumKeyExA(a0, a1, a2, a3, a4, a5, a6, a7); } LONG WINAPI Mine_RegEnumKeyExW(HKEY a0, DWORD a1, LPWSTR a2, LPDWORD a3, LPDWORD a4, LPWSTR a5, LPDWORD a6, struct _FILETIME* a7) { if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) { return ERROR_NO_MORE_ITEMS; } return Real_RegEnumKeyExW(a0, a1, a2, a3, a4, a5, a6, a7); } LONG WINAPI Mine_RegEnumValueA(HKEY a0, DWORD a1, LPSTR a2, LPDWORD a3, LPDWORD a4, LPDWORD a5, LPBYTE a6, LPDWORD a7) { if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) { return ERROR_NO_MORE_ITEMS; } return Real_RegEnumValueA(a0, a1, a2, a3, a4, a5, a6, a7); } LONG WINAPI Mine_RegEnumValueW(HKEY a0, DWORD a1, LPWSTR a2, LPDWORD a3, LPDWORD a4, LPDWORD a5, LPBYTE a6, LPDWORD a7) { if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) { return ERROR_NO_MORE_ITEMS; } return Real_RegEnumValueW(a0, a1, a2, a3, a4, a5, a6, a7); } LONG WINAPI Mine_RegOpenKeyA(HKEY a0, LPCSTR a1, PHKEY a2) { if(CFilterMapper2::m_pFilterMapper2) { *a2 = FAKEHKEY; return ERROR_SUCCESS; } return Real_RegOpenKeyA(a0, a1, a2); } LONG WINAPI Mine_RegOpenKeyW(HKEY a0, LPCWSTR a1, PHKEY a2) { if(CFilterMapper2::m_pFilterMapper2) { *a2 = FAKEHKEY; return ERROR_SUCCESS; } return Real_RegOpenKeyW(a0, a1, a2); } LONG WINAPI Mine_RegOpenKeyExA(HKEY a0, LPCSTR a1, DWORD a2, REGSAM a3, PHKEY a4) { if(CFilterMapper2::m_pFilterMapper2 && (a3&(KEY_SET_VALUE|KEY_CREATE_SUB_KEY))) { *a4 = FAKEHKEY; return ERROR_SUCCESS; } return Real_RegOpenKeyExA(a0, a1, a2, a3, a4); } LONG WINAPI Mine_RegOpenKeyExW(HKEY a0, LPCWSTR a1, DWORD a2, REGSAM a3, PHKEY a4) { if(CFilterMapper2::m_pFilterMapper2 && (a3&(KEY_SET_VALUE|KEY_CREATE_SUB_KEY))) { *a4 = FAKEHKEY; return ERROR_SUCCESS; } return Real_RegOpenKeyExW(a0, a1, a2, a3, a4); } LONG WINAPI Mine_RegQueryInfoKeyA(HKEY a0, LPSTR a1, LPDWORD a2, LPDWORD a3, LPDWORD a4, LPDWORD a5, LPDWORD a6, LPDWORD a7, LPDWORD a8, LPDWORD a9, LPDWORD a10, struct _FILETIME* a11) { if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) { return ERROR_INVALID_HANDLE; } return Real_RegQueryInfoKeyA(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); } LONG WINAPI Mine_RegQueryInfoKeyW(HKEY a0, LPWSTR a1, LPDWORD a2, LPDWORD a3, LPDWORD a4, LPDWORD a5, LPDWORD a6, LPDWORD a7, LPDWORD a8, LPDWORD a9, LPDWORD a10, struct _FILETIME* a11) { if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) { return ERROR_INVALID_HANDLE; } return Real_RegQueryInfoKeyW(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); } LONG WINAPI Mine_RegQueryValueA(HKEY a0, LPCSTR a1, LPSTR a2, PLONG a3) { if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) { *a3 = 0; return ERROR_SUCCESS; } return Real_RegQueryValueA(a0, a1, a2, a3); } LONG WINAPI Mine_RegQueryValueW(HKEY a0, LPCWSTR a1, LPWSTR a2, PLONG a3) { if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) { *a3 = 0; return ERROR_SUCCESS; } return Real_RegQueryValueW(a0, a1, a2, a3); } LONG WINAPI Mine_RegQueryValueExA(HKEY a0, LPCSTR a1, LPDWORD a2, LPDWORD a3, LPBYTE a4, LPDWORD a5) { if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) { *a5 = 0; return ERROR_SUCCESS; } return Real_RegQueryValueExA(a0, a1, a2, a3, a4, a5); } LONG WINAPI Mine_RegQueryValueExW(HKEY a0, LPCWSTR a1, LPDWORD a2, LPDWORD a3, LPBYTE a4, LPDWORD a5) { if(CFilterMapper2::m_pFilterMapper2 && a0 == FAKEHKEY) { *a5 = 0; return ERROR_SUCCESS; } return Real_RegQueryValueExW(a0, a1, a2, a3, a4, a5); } LONG WINAPI Mine_RegSetValueA(HKEY a0, LPCSTR a1, DWORD a2, LPCSTR a3, DWORD a4) { if(CFilterMapper2::m_pFilterMapper2 && (a0 == FAKEHKEY || (int)a0 < 0)) { return ERROR_SUCCESS; } return Real_RegSetValueA(a0, a1, a2, a3, a4); } LONG WINAPI Mine_RegSetValueW(HKEY a0, LPCWSTR a1, DWORD a2, LPCWSTR a3, DWORD a4) { if(CFilterMapper2::m_pFilterMapper2 && (a0 == FAKEHKEY || (int)a0 < 0)) { return ERROR_SUCCESS; } return Real_RegSetValueW(a0, a1, a2, a3, a4); } LONG WINAPI Mine_RegSetValueExA(HKEY a0, LPCSTR a1, DWORD a2, DWORD a3, BYTE* a4, DWORD a5) { if(CFilterMapper2::m_pFilterMapper2 && (a0 == FAKEHKEY || (int)a0 < 0)) { return ERROR_SUCCESS; } return Real_RegSetValueExA(a0, a1, a2, a3, a4, a5); } LONG WINAPI Mine_RegSetValueExW(HKEY a0, LPCWSTR a1, DWORD a2, DWORD a3, BYTE* a4, DWORD a5) { if(CFilterMapper2::m_pFilterMapper2 && (a0 == FAKEHKEY || (int)a0 < 0)) { return ERROR_SUCCESS; } return Real_RegSetValueExW(a0, a1, a2, a3, a4, a5); } // // CFilterMapper2 // IFilterMapper2* CFilterMapper2::m_pFilterMapper2 = NULL; bool CFilterMapper2::fInitialized = false; void CFilterMapper2::Init() { if(!fInitialized) { DetourAttach(&(PVOID&)Real_CoCreateInstance, (PVOID)Mine_CoCreateInstance); DetourAttach(&(PVOID&)Real_RegCloseKey, (PVOID)Mine_RegCloseKey); DetourAttach(&(PVOID&)Real_RegFlushKey, (PVOID)Mine_RegFlushKey); DetourAttach(&(PVOID&)Real_RegCreateKeyA, (PVOID)Mine_RegCreateKeyA); DetourAttach(&(PVOID&)Real_RegCreateKeyW, (PVOID)Mine_RegCreateKeyW); DetourAttach(&(PVOID&)Real_RegCreateKeyExA, (PVOID)Mine_RegCreateKeyExA); DetourAttach(&(PVOID&)Real_RegCreateKeyExW, (PVOID)Mine_RegCreateKeyExW); DetourAttach(&(PVOID&)Real_RegDeleteKeyA, (PVOID)Mine_RegDeleteKeyA); DetourAttach(&(PVOID&)Real_RegDeleteKeyW, (PVOID)Mine_RegDeleteKeyW); DetourAttach(&(PVOID&)Real_RegDeleteValueA, (PVOID)Mine_RegDeleteValueA); DetourAttach(&(PVOID&)Real_RegDeleteValueW, (PVOID)Mine_RegDeleteValueW); DetourAttach(&(PVOID&)Real_RegEnumKeyExA, (PVOID)Mine_RegEnumKeyExA); DetourAttach(&(PVOID&)Real_RegEnumKeyExW, (PVOID)Mine_RegEnumKeyExW); DetourAttach(&(PVOID&)Real_RegEnumValueA, (PVOID)Mine_RegEnumValueA); DetourAttach(&(PVOID&)Real_RegEnumValueW, (PVOID)Mine_RegEnumValueW); DetourAttach(&(PVOID&)Real_RegOpenKeyA, (PVOID)Mine_RegOpenKeyA); DetourAttach(&(PVOID&)Real_RegOpenKeyW, (PVOID)Mine_RegOpenKeyW); DetourAttach(&(PVOID&)Real_RegOpenKeyExA, (PVOID)Mine_RegOpenKeyExA); DetourAttach(&(PVOID&)Real_RegOpenKeyExW, (PVOID)Mine_RegOpenKeyExW); DetourAttach(&(PVOID&)Real_RegQueryInfoKeyA, (PVOID)Mine_RegQueryInfoKeyA); DetourAttach(&(PVOID&)Real_RegQueryInfoKeyW, (PVOID)Mine_RegQueryInfoKeyW); DetourAttach(&(PVOID&)Real_RegQueryValueA, (PVOID)Mine_RegQueryValueA); DetourAttach(&(PVOID&)Real_RegQueryValueW, (PVOID)Mine_RegQueryValueW); DetourAttach(&(PVOID&)Real_RegQueryValueExA, (PVOID)Mine_RegQueryValueExA); DetourAttach(&(PVOID&)Real_RegQueryValueExW, (PVOID)Mine_RegQueryValueExW); DetourAttach(&(PVOID&)Real_RegSetValueA, (PVOID)Mine_RegSetValueA); DetourAttach(&(PVOID&)Real_RegSetValueW, (PVOID)Mine_RegSetValueW); DetourAttach(&(PVOID&)Real_RegSetValueExA, (PVOID)Mine_RegSetValueExA); DetourAttach(&(PVOID&)Real_RegSetValueExW, (PVOID)Mine_RegSetValueExW); fInitialized = true; } } CFilterMapper2::CFilterMapper2(bool fRefCounted, bool fAllowUnreg, LPUNKNOWN pUnkOuter) : CUnknown(NAME("CFilterMapper2"), pUnkOuter) , m_fRefCounted(fRefCounted), m_fAllowUnreg(fAllowUnreg) { m_cRef = fRefCounted ? 0 : 1; Init(); HRESULT hr = Real_CoCreateInstance( CLSID_FilterMapper2, (IUnknown*)(INonDelegatingUnknown*)this, CLSCTX_ALL, __uuidof(IUnknown), (void**)&m_pFM2); if(FAILED(hr) || !m_pFM2) { ASSERT(0); return; } } CFilterMapper2::~CFilterMapper2() { POSITION pos = m_filters.GetHeadPosition(); while(pos) delete m_filters.GetNext(pos); } STDMETHODIMP CFilterMapper2::NonDelegatingQueryInterface(REFIID riid, void** ppv) { if(riid == __uuidof(IFilterMapper2)) return GetInterface((IFilterMapper2*)this, ppv); HRESULT hr = m_pFM2 ? m_pFM2->QueryInterface(riid, ppv) : E_NOINTERFACE; return SUCCEEDED(hr) ? hr : __super::NonDelegatingQueryInterface(riid, ppv); } void CFilterMapper2::Register(CString path) { if(HMODULE h = LoadLibrary(path)) { typedef HRESULT (__stdcall * PDllRegisterServer)(); if(PDllRegisterServer p = (PDllRegisterServer)GetProcAddress(h, "DllRegisterServer")) { ASSERT(CFilterMapper2::m_pFilterMapper2 == NULL); CFilterMapper2::m_pFilterMapper2 = this; m_path = path; p(); m_path.Empty(); CFilterMapper2::m_pFilterMapper2 = NULL; } FreeLibrary(h); } } // IFilterMapper2 STDMETHODIMP CFilterMapper2::CreateCategory(REFCLSID clsidCategory, DWORD dwCategoryMerit, LPCWSTR Description) { if(!m_path.IsEmpty()) { return S_OK; } else if(CComQIPtr pFM2 = m_pFM2) { return pFM2->CreateCategory(clsidCategory, dwCategoryMerit, Description); } return E_NOTIMPL; } STDMETHODIMP CFilterMapper2::UnregisterFilter(const CLSID* pclsidCategory, const OLECHAR* szInstance, REFCLSID Filter) { if(!m_path.IsEmpty()) { return S_OK; } else if(CComQIPtr pFM2 = m_pFM2) { return m_fAllowUnreg ? pFM2->UnregisterFilter(pclsidCategory, szInstance, Filter) : S_OK; } return E_NOTIMPL; } STDMETHODIMP CFilterMapper2::RegisterFilter(REFCLSID clsidFilter, LPCWSTR Name, IMoniker** ppMoniker, const CLSID* pclsidCategory, const OLECHAR* szInstance, const REGFILTER2* prf2) { if(!m_path.IsEmpty()) { if(FilterOverride* f = DNew FilterOverride) { f->fDisabled = false; f->type = FilterOverride::EXTERNAL; f->path = m_path; f->name = CStringW(Name); f->clsid = clsidFilter; f->iLoadType = FilterOverride::MERIT; f->dwMerit = prf2->dwMerit; if(prf2->dwVersion == 1) { for(ULONG i = 0; i < prf2->cPins; i++) { const REGFILTERPINS& rgPin = prf2->rgPins[i]; if(rgPin.bOutput) continue; for(UINT i = 0; i < rgPin.nMediaTypes; i++) { if(!rgPin.lpMediaType[i].clsMajorType || !rgPin.lpMediaType[i].clsMinorType) break; f->guids.AddTail(*rgPin.lpMediaType[i].clsMajorType); f->guids.AddTail(*rgPin.lpMediaType[i].clsMinorType); } } } else if(prf2->dwVersion == 2) { for(ULONG i = 0; i < prf2->cPins2; i++) { const REGFILTERPINS2& rgPin = prf2->rgPins2[i]; if(rgPin.dwFlags®_PINFLAG_B_OUTPUT) continue; for(UINT i = 0; i < rgPin.nMediaTypes; i++) { if(!rgPin.lpMediaType[i].clsMajorType || !rgPin.lpMediaType[i].clsMinorType) break; f->guids.AddTail(*rgPin.lpMediaType[i].clsMajorType); f->guids.AddTail(*rgPin.lpMediaType[i].clsMinorType); } } } f->backup.AddTailList(&f->guids); m_filters.AddTail(f); } return S_OK; } else if(CComQIPtr pFM2 = m_pFM2) { return pFM2->RegisterFilter(clsidFilter, Name, ppMoniker, pclsidCategory, szInstance, prf2); } return E_NOTIMPL; } STDMETHODIMP CFilterMapper2::EnumMatchingFilters(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) { if(CComQIPtr pFM2 = m_pFM2) { pFM2->EnumMatchingFilters(ppEnum, dwFlags, bExactMatch, dwMerit, bInputNeeded, cInputTypes, pInputTypes, pMedIn, pPinCategoryIn, bRender, bOutputNeeded, cOutputTypes, pOutputTypes, pMedOut, pPinCategoryOut); } return E_NOTIMPL; }