[95] | 1 | //////////////////////////////////////////////////////////// |
---|
[376] | 2 | // Copyright (C) Roman Ryltsov, 2008-2015 |
---|
[276] | 3 | // Created by Roman Ryltsov roman@alax.info, http://alax.info |
---|
[267] | 4 | // |
---|
| 5 | // This source code is published to complement DirectShowSpy developer powertoy |
---|
| 6 | // and demonstrate the internal use of APIs and tricks powering the tool. It is |
---|
[276] | 7 | // allowed to freely re-use the portions of the code in other projects, commercial |
---|
| 8 | // or otherwise (provided that you dont pretend that you wrote the original tool). |
---|
[267] | 9 | // |
---|
| 10 | // Please keep in mind that DirectShowSpy is a developer tool, it is strongly recommended |
---|
[276] | 11 | // that it is not shipped with release grade software. It is allowed to distribute |
---|
| 12 | // DirectShowSpy if only it is not registered with Windows by default and either |
---|
| 13 | // used privately, or registered on specific throubleshooting request. The advice applies |
---|
| 14 | // to hooking methods used by DirectShowSpy in general as well. |
---|
[95] | 15 | |
---|
| 16 | #pragma once |
---|
| 17 | |
---|
| 18 | #include "rodshow.h" |
---|
[545] | 19 | #include "fil_data.h" //<..\Samples\multimedia\directshow\misc\mapper\fil_data.h> |
---|
[310] | 20 | #include "Module_i.h" |
---|
[95] | 21 | #include "Common.h" |
---|
| 22 | |
---|
| 23 | //////////////////////////////////////////////////////////// |
---|
| 24 | // CFilterMapperSpyT |
---|
| 25 | |
---|
| 26 | template <typename T, const CLSID* t_pFilterMapperClassIdentifier> |
---|
| 27 | class ATL_NO_VTABLE CFilterMapperSpyT : |
---|
| 28 | public CComObjectRootEx<CComMultiThreadModel>, |
---|
| 29 | //public CComCoClass<CFilterMapperSpyT, &CLSID_FilterMapperSpy>, |
---|
| 30 | public CTransparentCoClassT<T, t_pFilterMapperClassIdentifier>, |
---|
| 31 | public IDispatchImpl<IFilterMapperSpy>, |
---|
| 32 | public IAMFilterData, |
---|
[545] | 33 | public IFilterMapper, |
---|
| 34 | public IFilterMapper3 |
---|
[95] | 35 | { |
---|
| 36 | typedef CFilterMapperSpyT<T, t_pFilterMapperClassIdentifier> CFilterMapperSpy; |
---|
| 37 | |
---|
| 38 | public: |
---|
| 39 | //enum { IDR = IDR_FILTERMAPPERSPY }; |
---|
| 40 | |
---|
| 41 | //DECLARE_REGISTRY_RESOURCEID(IDR) |
---|
| 42 | |
---|
| 43 | DECLARE_PROTECT_FINAL_CONSTRUCT() |
---|
| 44 | |
---|
| 45 | DECLARE_GET_CONTROLLING_UNKNOWN() |
---|
| 46 | |
---|
[545] | 47 | DECLARE_QI_TRACE(CFilterMapperSpyT) |
---|
[95] | 48 | |
---|
[545] | 49 | BEGIN_COM_MAP(CFilterMapperSpyT) |
---|
[95] | 50 | COM_INTERFACE_ENTRY(IFilterMapperSpy) |
---|
| 51 | COM_INTERFACE_ENTRY(IAMFilterData) |
---|
[545] | 52 | COM_INTERFACE_ENTRY(IFilterMapper3) |
---|
[95] | 53 | COM_INTERFACE_ENTRY(IFilterMapper2) |
---|
[545] | 54 | COM_INTERFACE_ENTRY(IFilterMapper) |
---|
[95] | 55 | COM_INTERFACE_ENTRY_AGGREGATE_BLIND(m_pInnerUnknown) |
---|
| 56 | //COM_INTERFACE_ENTRY(IDispatch) |
---|
| 57 | END_COM_MAP() |
---|
| 58 | |
---|
| 59 | private: |
---|
| 60 | BOOL m_bIsAggregated; |
---|
| 61 | HINSTANCE m_hQuartzModule; |
---|
| 62 | CComPtr<IUnknown> m_pInnerUnknown; |
---|
[545] | 63 | CComPtr<IFilterMapper3> m_pFilterMapper3; |
---|
| 64 | CComPtr<IFilterMapper> m_pFilterMapper; |
---|
[95] | 65 | CComPtr<IAMFilterData> m_pAmFilterData; |
---|
| 66 | |
---|
| 67 | static VOID Trace(const REGFILTER2* pFilterInformation) |
---|
| 68 | { |
---|
| 69 | _A(pFilterInformation); |
---|
[545] | 70 | _Z4(atlTraceCOM, 4, _T("pFilterInformation { dwVersion %d, dwMerit 0x%08X, cPins2 %d }\n"), pFilterInformation->dwVersion, pFilterInformation->dwMerit, pFilterInformation->cPins2); |
---|
[95] | 71 | if(pFilterInformation->dwVersion == 2) |
---|
| 72 | for(ULONG nPinIndex = 0; nPinIndex < pFilterInformation->cPins2; nPinIndex++) |
---|
| 73 | { |
---|
| 74 | const REGFILTERPINS2& Pin = pFilterInformation->rgPins2[nPinIndex]; |
---|
[545] | 75 | _Z4(atlTraceCOM, 4, _T("pFilterInformation->rgPins2[%d] { dwFlags 0x%X, cInstances %d, nMediaTypes %d, nMediums %d }\n"), nPinIndex, Pin.dwFlags, Pin.cInstances, Pin.nMediaTypes, Pin.nMediums, Pin.clsPinCategory ? (LPCWSTR) _PersistHelper::StringFromIdentifier(*Pin.clsPinCategory) : L"NULL"); |
---|
[95] | 76 | for(UINT nIndex = 0; nIndex < Pin.nMediaTypes; nIndex++) |
---|
| 77 | { |
---|
| 78 | const REGPINTYPES& Type = Pin.lpMediaType[nIndex]; |
---|
| 79 | _Z4(atlTraceCOM, 4, _T("pFilterInformation->rgPins2[...].lpMediaType[%d] { clsMajorType %ls, clsMinorType %ls }\n"), nIndex, Type.clsMajorType ? (LPCWSTR) _PersistHelper::StringFromIdentifier(*Type.clsMajorType) : L"NULL", Type.clsMinorType ? (LPCWSTR) _PersistHelper::StringFromIdentifier(*Type.clsMinorType) : L"NULL"); |
---|
| 80 | } |
---|
| 81 | for(UINT nIndex = 0; nIndex < Pin.nMediums; nIndex++) |
---|
| 82 | { |
---|
| 83 | const REGPINMEDIUM& Medium = Pin.lpMedium[nIndex]; |
---|
[545] | 84 | _Z4(atlTraceCOM, 4, _T("pFilterInformation->rgPins2[...].lpMedium[%d] { clsMedium %ls, dw1 0x%X, dw2 0x%X }\n"), nIndex, _PersistHelper::StringFromIdentifier(Medium.clsMedium), Medium.dw1, Medium.dw2); |
---|
[95] | 85 | } |
---|
| 86 | } |
---|
| 87 | } |
---|
[545] | 88 | BOOL IsAggregated() const |
---|
[95] | 89 | { |
---|
| 90 | return (ULONG) m_dwRef >= 0x00001000; |
---|
| 91 | } |
---|
| 92 | |
---|
| 93 | public: |
---|
| 94 | // CFilterMapperSpyT |
---|
[545] | 95 | static LPCTSTR GetOriginalLibraryName() |
---|
[95] | 96 | { |
---|
| 97 | return _T("quartz.dll"); |
---|
| 98 | } |
---|
| 99 | static CString GetObjectFriendlyName() |
---|
| 100 | { |
---|
| 101 | return _StringHelper::GetLine(T::IDR, 2); |
---|
| 102 | } |
---|
[545] | 103 | static HRESULT WINAPI UpdateRegistry(BOOL bRegister) |
---|
[95] | 104 | { |
---|
| 105 | _Z2(atlTraceRegistrar, 2, _T("bRegister %d\n"), bRegister); |
---|
| 106 | _ATLTRY |
---|
| 107 | { |
---|
| 108 | TreatAsUpdateRegistryFromResource<T>(*t_pFilterMapperClassIdentifier, bRegister); |
---|
| 109 | } |
---|
| 110 | _ATLCATCH(Exception) |
---|
| 111 | { |
---|
| 112 | _C(Exception); |
---|
| 113 | } |
---|
| 114 | return S_OK; |
---|
| 115 | } |
---|
[545] | 116 | CFilterMapperSpyT() : |
---|
[95] | 117 | m_hQuartzModule(NULL) |
---|
| 118 | { |
---|
[319] | 119 | _Z4_THIS(); |
---|
[95] | 120 | } |
---|
[545] | 121 | ~CFilterMapperSpyT() |
---|
[95] | 122 | { |
---|
[319] | 123 | _Z4_THIS(); |
---|
[95] | 124 | } |
---|
[545] | 125 | HRESULT FinalConstruct() |
---|
[95] | 126 | { |
---|
| 127 | _ATLTRY |
---|
| 128 | { |
---|
| 129 | m_bIsAggregated = IsAggregated(); |
---|
| 130 | TCHAR pszPath[MAX_PATH] = { 0 }; |
---|
| 131 | _W(GetModuleFileName(NULL, pszPath, DIM(pszPath))); |
---|
[545] | 132 | _Z4(atlTraceRefcount, 4, _T("pszPath \"%s\", this 0x%p, m_dwRef %d, m_bIsAggregated %d\n"), pszPath, this, m_dwRef, m_bIsAggregated); |
---|
[144] | 133 | const HINSTANCE hModule = CoLoadLibrary(const_cast<LPOLESTR>((LPCOLESTR) CT2COLE(GetOriginalLibraryName())), TRUE); |
---|
[95] | 134 | _ATLTRY |
---|
| 135 | { |
---|
| 136 | typedef HRESULT (WINAPI *DLLGETCLASSOBJECT)(REFCLSID, REFIID, VOID**); |
---|
| 137 | DLLGETCLASSOBJECT DllGetClassObject = (DLLGETCLASSOBJECT) GetProcAddress(hModule, "DllGetClassObject"); |
---|
| 138 | __E(DllGetClassObject); |
---|
| 139 | CComPtr<IClassFactory> pClassFactory; |
---|
| 140 | __C(DllGetClassObject(*t_pFilterMapperClassIdentifier, __uuidof(IClassFactory), (VOID**) &pClassFactory)); |
---|
| 141 | _A(pClassFactory); |
---|
| 142 | const CComPtr<IUnknown> pControllingUnknown = GetControllingUnknown(); |
---|
| 143 | { |
---|
| 144 | CComPtr<IUnknown> pUnknown; |
---|
| 145 | __C(pClassFactory->CreateInstance(pControllingUnknown, __uuidof(IUnknown), (VOID**) &pUnknown)); |
---|
[545] | 146 | const CComQIPtr<IFilterMapper3> pFilterMapper3 = pUnknown; |
---|
| 147 | __D(pFilterMapper3, E_NOINTERFACE); |
---|
| 148 | pFilterMapper3.p->Release(); |
---|
| 149 | const CComQIPtr<IFilterMapper> pFilterMapper = pUnknown; |
---|
| 150 | __D(pFilterMapper, E_NOINTERFACE); |
---|
| 151 | pFilterMapper.p->Release(); |
---|
[95] | 152 | const CComQIPtr<IAMFilterData> pAmFilterData = pUnknown; |
---|
| 153 | __D(pAmFilterData, E_NOINTERFACE); |
---|
| 154 | pAmFilterData.p->Release(); |
---|
| 155 | m_pInnerUnknown = pUnknown; |
---|
[545] | 156 | m_pFilterMapper3 = pFilterMapper3; |
---|
| 157 | m_pFilterMapper = pFilterMapper; |
---|
[95] | 158 | m_pAmFilterData = pAmFilterData; |
---|
| 159 | } |
---|
| 160 | } |
---|
| 161 | _ATLCATCHALL() |
---|
| 162 | { |
---|
| 163 | CoFreeLibrary(hModule); |
---|
| 164 | _ATLRETHROW; |
---|
| 165 | } |
---|
| 166 | _A(!m_hQuartzModule); |
---|
| 167 | m_hQuartzModule = hModule; |
---|
| 168 | } |
---|
| 169 | _ATLCATCH(Exception) |
---|
| 170 | { |
---|
| 171 | _C(Exception); |
---|
| 172 | } |
---|
| 173 | return S_OK; |
---|
| 174 | } |
---|
[545] | 175 | VOID FinalRelease() |
---|
[95] | 176 | { |
---|
[545] | 177 | _Z5(atlTraceRefcount, 5, _T("m_dwRef 0x%X\n"), m_dwRef); |
---|
[95] | 178 | CComPtr<IUnknown> pControllingUnknown = GetControllingUnknown(); |
---|
[545] | 179 | if(m_pFilterMapper3) |
---|
[95] | 180 | { |
---|
| 181 | pControllingUnknown.p->AddRef(); |
---|
[545] | 182 | m_pFilterMapper3.Release(); |
---|
[95] | 183 | } |
---|
[545] | 184 | if(m_pFilterMapper) |
---|
| 185 | { |
---|
| 186 | pControllingUnknown.p->AddRef(); |
---|
| 187 | m_pFilterMapper.Release(); |
---|
| 188 | } |
---|
[95] | 189 | if(m_pAmFilterData) |
---|
| 190 | { |
---|
| 191 | pControllingUnknown.p->AddRef(); |
---|
[545] | 192 | m_pAmFilterData.Release(); |
---|
[95] | 193 | } |
---|
| 194 | _ATLTRY |
---|
| 195 | { |
---|
[545] | 196 | m_pInnerUnknown.Release(); |
---|
[95] | 197 | } |
---|
| 198 | _ATLCATCHALL() |
---|
| 199 | { |
---|
| 200 | _Z_EXCEPTION(); |
---|
| 201 | // NOTE: For some unidentified reason Quartz's FilterGraph may crash during final release, to smooth the effect the exception is silently caught |
---|
| 202 | m_pInnerUnknown.p = NULL; |
---|
| 203 | } |
---|
| 204 | if(m_hQuartzModule) |
---|
| 205 | { |
---|
| 206 | CoFreeLibrary(m_hQuartzModule); |
---|
| 207 | m_hQuartzModule = NULL; |
---|
| 208 | } |
---|
| 209 | } |
---|
| 210 | |
---|
| 211 | // IFilterMapperSpy |
---|
| 212 | |
---|
| 213 | // IAMFilterData |
---|
[545] | 214 | STDMETHOD(ParseFilterData)(BYTE* pnFilterData, ULONG nFilterDataSize, BYTE** ppFilterInformation) override |
---|
[95] | 215 | { |
---|
| 216 | _Z4(atlTraceCOM, 4, _T("nFilterDataSize %d\n"), nFilterDataSize); |
---|
| 217 | const HRESULT nResult = m_pAmFilterData->ParseFilterData(pnFilterData, nFilterDataSize, ppFilterInformation); |
---|
| 218 | if(SUCCEEDED(nResult) && ppFilterInformation && *ppFilterInformation && *((BYTE**) *ppFilterInformation)) |
---|
| 219 | _ATLTRY |
---|
| 220 | { |
---|
| 221 | Trace((REGFILTER2*) *((BYTE**) *ppFilterInformation)); |
---|
| 222 | } |
---|
| 223 | _ATLCATCHALL() |
---|
| 224 | { |
---|
| 225 | _Z_EXCEPTION(); |
---|
| 226 | } |
---|
| 227 | return nResult; |
---|
| 228 | } |
---|
[545] | 229 | STDMETHOD(CreateFilterData)(REGFILTER2* pFilterInformation, BYTE** ppnFilterData, ULONG* pnFilterDataSize) override |
---|
[95] | 230 | { |
---|
| 231 | _Z4(atlTraceCOM, 4, _T("...\n")); |
---|
| 232 | if(pFilterInformation) |
---|
| 233 | _ATLTRY |
---|
| 234 | { |
---|
| 235 | Trace(pFilterInformation); |
---|
| 236 | } |
---|
| 237 | _ATLCATCHALL() |
---|
| 238 | { |
---|
| 239 | _Z_EXCEPTION(); |
---|
| 240 | } |
---|
| 241 | return m_pAmFilterData->CreateFilterData(pFilterInformation, ppnFilterData, pnFilterDataSize); |
---|
| 242 | } |
---|
| 243 | |
---|
[545] | 244 | // IFilterMapper3 |
---|
| 245 | STDMETHOD(GetICreateDevEnum)(ICreateDevEnum** ppEnum) override |
---|
| 246 | { |
---|
| 247 | _Z4(atlTraceCOM, 4, _T("...\n")); |
---|
| 248 | return m_pFilterMapper3->GetICreateDevEnum(ppEnum); |
---|
| 249 | } |
---|
| 250 | |
---|
[95] | 251 | // IFilterMapper2 |
---|
[545] | 252 | STDMETHOD(CreateCategory)(REFCLSID CategoryIdentifier, DWORD nMerit, LPCWSTR pszDescription) override |
---|
[95] | 253 | { |
---|
[545] | 254 | _Z4(atlTraceCOM, 4, _T("CategoryIdentifier %ls, nMerit 0x%08X, pszDescription \"%s\"\n"), _PersistHelper::StringFromIdentifier(CategoryIdentifier), nMerit, CString(pszDescription)); |
---|
| 255 | return m_pFilterMapper3->CreateCategory(CategoryIdentifier, nMerit, pszDescription); |
---|
[95] | 256 | } |
---|
[545] | 257 | STDMETHOD(UnregisterFilter)(const CLSID* pCategoryIdentifier, LPCOLESTR pszInstance, REFCLSID FilterClassIdentifier) override |
---|
[95] | 258 | { |
---|
| 259 | _Z4(atlTraceCOM, 4, _T("pCategoryIdentifier %ls, pszInstance %s, FilterClassIdentifier %ls\n"), pCategoryIdentifier ? (LPCWSTR) _PersistHelper::StringFromIdentifier(*pCategoryIdentifier) : L"NULL", pszInstance ? (LPCTSTR) AtlFormatString(_T("\"%s\""), CString(pszInstance)) : _T("NULL"), _PersistHelper::StringFromIdentifier(FilterClassIdentifier)); |
---|
[545] | 260 | return m_pFilterMapper3->UnregisterFilter(pCategoryIdentifier, pszInstance, FilterClassIdentifier); |
---|
[95] | 261 | } |
---|
[545] | 262 | STDMETHOD(RegisterFilter)(REFCLSID FilterClassIdentifier, LPCWSTR pszName, IMoniker** ppMoniker, const CLSID* pCategoryIdentifier, LPCOLESTR pszInstance, const REGFILTER2* pFilterInformation) override |
---|
[95] | 263 | { |
---|
| 264 | _Z4(atlTraceCOM, 4, _T("FilterClassIdentifier %ls, pszName \"%s\", pCategoryIdentifier %ls, pszInstance %s\n"), _PersistHelper::StringFromIdentifier(FilterClassIdentifier), CString(pszName), pCategoryIdentifier ? (LPCWSTR) _PersistHelper::StringFromIdentifier(*pCategoryIdentifier) : L"NULL", pszInstance ? (LPCTSTR) AtlFormatString(_T("\"%s\""), CString(pszInstance)) : _T("NULL")); |
---|
| 265 | if(pFilterInformation) |
---|
| 266 | _ATLTRY |
---|
| 267 | { |
---|
| 268 | Trace(pFilterInformation); |
---|
| 269 | } |
---|
| 270 | _ATLCATCHALL() |
---|
| 271 | { |
---|
| 272 | _Z_EXCEPTION(); |
---|
| 273 | } |
---|
[545] | 274 | return m_pFilterMapper3->RegisterFilter(FilterClassIdentifier, pszName, ppMoniker, pCategoryIdentifier, pszInstance, pFilterInformation); |
---|
[95] | 275 | } |
---|
[545] | 276 | STDMETHOD(EnumMatchingFilters)(IEnumMoniker** ppEnumMoniker, DWORD nFlags, BOOL bExactMatch, DWORD nMinimalMerit, BOOL bInputNeeded, DWORD nInputTypeCount, const GUID* pInputTypes, const REGPINMEDIUM* pInputMedium, const CLSID* pInputPinCategory, BOOL bRender, BOOL bOutputNeeded, DWORD nOutputTypeCount, const GUID* pOutputTypes, const REGPINMEDIUM* pOutputMedium, const CLSID* pOutputPinCategory) override |
---|
[95] | 277 | { |
---|
[545] | 278 | _Z4(atlTraceCOM, 4, _T("nFlags 0x%X, bExactMatch %d, nMinimalMerit 0x%08X, bInputNeeded %d, nInputTypeCount %d, pInputPinCategory %ls, bRender %d, bOutputNeeded %d, nOutputTypeCount %d, pOutputPinCategory %ls\n"), nFlags, bExactMatch, nMinimalMerit, bInputNeeded, nInputTypeCount, pInputPinCategory ? (LPCWSTR) _PersistHelper::StringFromIdentifier(*pInputPinCategory) : L"NULL", bRender, bOutputNeeded, nOutputTypeCount, pOutputPinCategory ? (LPCWSTR) _PersistHelper::StringFromIdentifier(*pOutputPinCategory) : L"NULL"); |
---|
[95] | 279 | for(DWORD nInputTypeIndex = 0; nInputTypeIndex < nInputTypeCount; nInputTypeIndex++) |
---|
| 280 | { |
---|
| 281 | const GUID& MajorType = pInputTypes[2 * nInputTypeIndex + 0]; |
---|
| 282 | const GUID& Subtype = pInputTypes[2 * nInputTypeIndex + 1]; |
---|
| 283 | _Z4(atlTraceCOM, 4, _T("nInputTypeIndex %d, MajorType %ls, Subtype %ls\n"), nInputTypeIndex, _PersistHelper::StringFromIdentifier(MajorType), _PersistHelper::StringFromIdentifier(Subtype)); |
---|
| 284 | } |
---|
| 285 | if(pInputMedium) |
---|
[545] | 286 | _Z4(atlTraceCOM, 4, _T("pInputMedium { clsMedium %ls, dw1 0x%X, dw2 0x%X }\n"), _PersistHelper::StringFromIdentifier(pInputMedium->clsMedium), pInputMedium->dw1, pInputMedium->dw2); |
---|
[95] | 287 | for(DWORD nOutputTypeIndex = 0; nOutputTypeIndex < nOutputTypeCount; nOutputTypeIndex++) |
---|
| 288 | { |
---|
| 289 | const GUID& MajorType = pOutputTypes[2 * nOutputTypeIndex + 0]; |
---|
| 290 | const GUID& Subtype = pOutputTypes[2 * nOutputTypeIndex + 1]; |
---|
| 291 | _Z4(atlTraceCOM, 4, _T("nOutputTypeIndex %d, MajorType %ls, Subtype %ls\n"), nOutputTypeIndex, _PersistHelper::StringFromIdentifier(MajorType), _PersistHelper::StringFromIdentifier(Subtype)); |
---|
| 292 | } |
---|
| 293 | if(pOutputMedium) |
---|
[545] | 294 | _Z4(atlTraceCOM, 4, _T("pOutputMedium { clsMedium %ls, dw1 0x%X, dw2 0x%X }\n"), _PersistHelper::StringFromIdentifier(pOutputMedium->clsMedium), pOutputMedium->dw1, pOutputMedium->dw2); |
---|
| 295 | const HRESULT nResult = m_pFilterMapper3->EnumMatchingFilters(ppEnumMoniker, nFlags, bExactMatch, nMinimalMerit, bInputNeeded, nInputTypeCount, pInputTypes, pInputMedium, pInputPinCategory, bRender, bOutputNeeded, nOutputTypeCount, pOutputTypes, pOutputMedium, pOutputPinCategory); |
---|
[95] | 296 | if(SUCCEEDED(nResult)) |
---|
| 297 | _ATLTRY |
---|
| 298 | { |
---|
| 299 | const CComPtr<IEnumMoniker>& pEnumMoniker = reinterpret_cast<const CComPtr<IEnumMoniker>&>(*ppEnumMoniker); |
---|
| 300 | __C(pEnumMoniker->Reset()); |
---|
[545] | 301 | for(; ; ) |
---|
[95] | 302 | { |
---|
[545] | 303 | CComPtr<IMoniker> pMoniker; |
---|
| 304 | ULONG nElementCount; |
---|
| 305 | if(pEnumMoniker->Next(1, &pMoniker, &nElementCount) != S_OK) |
---|
| 306 | break; |
---|
| 307 | _Z4(atlTraceGeneral, 4, _T("pMoniker %ls\n"), _FilterGraphHelper::GetMonikerDisplayName(pMoniker)); |
---|
[95] | 308 | CComPtr<IBindCtx> pBindCtx; |
---|
| 309 | __C(CreateBindCtx(0, &pBindCtx)); |
---|
| 310 | CComPtr<IPropertyBag> pPropertyBag; |
---|
| 311 | __C(pMoniker->BindToStorage(pBindCtx, NULL, __uuidof(IPropertyBag), (VOID**) &pPropertyBag)); |
---|
| 312 | const CStringW sFriendlyName = _FilterGraphHelper::ReadPropertyBagString(pPropertyBag, OLESTR("FriendlyName")); |
---|
| 313 | const CStringW sDescription = _FilterGraphHelper::ReadPropertyBagString(pPropertyBag, OLESTR("Description")); |
---|
| 314 | const CStringW sDevicePath = _FilterGraphHelper::ReadPropertyBagString(pPropertyBag, OLESTR("DevicePath")); |
---|
| 315 | _Z4(atlTraceCOM, 4, _T("sFriendlyName \"%ls\", sDescription \"%ls\", sDevicePath \"%ls\"\n"), sFriendlyName, sDescription, sDevicePath); |
---|
| 316 | } |
---|
| 317 | __C(pEnumMoniker->Reset()); |
---|
| 318 | } |
---|
| 319 | _ATLCATCHALL() |
---|
| 320 | { |
---|
| 321 | _Z_EXCEPTION(); |
---|
| 322 | } |
---|
| 323 | return nResult; |
---|
| 324 | } |
---|
[545] | 325 | |
---|
| 326 | // IFilterMapper |
---|
| 327 | STDMETHOD(RegisterFilter)(CLSID FilterClassIdentifier, LPCWSTR pszName, DWORD nMerit) override |
---|
| 328 | { |
---|
| 329 | _Z4(atlTraceCOM, 4, _T("...\n")); |
---|
| 330 | return m_pFilterMapper->RegisterFilter(FilterClassIdentifier, pszName, nMerit); |
---|
| 331 | } |
---|
| 332 | STDMETHOD(RegisterFilterInstance)(CLSID FilterClassIdentifier, LPCWSTR pszName, CLSID* pMediaResourceIdentifier) override |
---|
| 333 | { |
---|
| 334 | _Z4(atlTraceCOM, 4, _T("...\n")); |
---|
| 335 | return m_pFilterMapper->RegisterFilterInstance(FilterClassIdentifier, pszName, pMediaResourceIdentifier); |
---|
| 336 | } |
---|
| 337 | STDMETHOD(RegisterPin)(CLSID Filter, LPCWSTR pszName, BOOL bRendered, BOOL bOutput, BOOL bZero, BOOL bMany, CLSID ConnectsToFilter, LPCWSTR pszConnectsToPin) override |
---|
| 338 | { |
---|
| 339 | _Z4(atlTraceCOM, 4, _T("...\n")); |
---|
| 340 | return m_pFilterMapper->RegisterPin(Filter, pszName, bRendered, bOutput, bZero, bMany, ConnectsToFilter, pszConnectsToPin); |
---|
| 341 | } |
---|
| 342 | STDMETHOD(RegisterPinType)(CLSID FilterClassIdentifier, LPCWSTR pszName, CLSID MajorType, CLSID Subtype) override |
---|
| 343 | { |
---|
| 344 | _Z4(atlTraceCOM, 4, _T("...\n")); |
---|
| 345 | return m_pFilterMapper->RegisterPinType(FilterClassIdentifier, pszName, MajorType, Subtype); |
---|
| 346 | } |
---|
| 347 | STDMETHOD(UnregisterFilter)(CLSID FilterClassIdentifier) override |
---|
| 348 | { |
---|
| 349 | _Z4(atlTraceCOM, 4, _T("...\n")); |
---|
| 350 | return m_pFilterMapper->UnregisterFilter(FilterClassIdentifier); |
---|
| 351 | } |
---|
| 352 | STDMETHOD(UnregisterFilterInstance)(CLSID MediaResourceIdentifier) override |
---|
| 353 | { |
---|
| 354 | _Z4(atlTraceCOM, 4, _T("...\n")); |
---|
| 355 | return m_pFilterMapper->UnregisterFilterInstance(MediaResourceIdentifier); |
---|
| 356 | } |
---|
| 357 | STDMETHOD(UnregisterPin)(CLSID FilterClassIdentifier, LPCWSTR pszName) override |
---|
| 358 | { |
---|
| 359 | _Z4(atlTraceCOM, 4, _T("...\n")); |
---|
| 360 | return m_pFilterMapper->UnregisterPin(FilterClassIdentifier, pszName); |
---|
| 361 | } |
---|
| 362 | STDMETHOD(EnumMatchingFilters)(IEnumRegFilters** ppEnum, DWORD nMerit, BOOL bInputNeeded, CLSID clsInMaj, CLSID clsInSub, BOOL bRender, BOOL bOutputNeeded, CLSID clsOutMaj, CLSID clsOutSub) override |
---|
| 363 | { |
---|
| 364 | _Z4(atlTraceCOM, 4, _T("...\n")); |
---|
| 365 | return m_pFilterMapper->EnumMatchingFilters(ppEnum, nMerit, bInputNeeded, clsInMaj, clsInSub, bRender, bOutputNeeded, clsOutMaj, clsOutSub); |
---|
| 366 | } |
---|
[95] | 367 | }; |
---|
| 368 | |
---|
| 369 | //////////////////////////////////////////////////////////// |
---|
| 370 | // CFilterMapperSpy |
---|
| 371 | |
---|
| 372 | class ATL_NO_VTABLE CFilterMapperSpy : |
---|
| 373 | public CFilterMapperSpyT<CFilterMapperSpy, &CLSID_FilterMapper2>, |
---|
| 374 | public CComCoClass<CFilterMapperSpy, &CLSID_FilterMapperSpy> |
---|
| 375 | { |
---|
| 376 | public: |
---|
| 377 | enum { IDR = IDR_FILTERMAPPERSPY }; |
---|
| 378 | |
---|
| 379 | private: |
---|
| 380 | static LPCTSTR g_pszClassName; |
---|
| 381 | |
---|
| 382 | public: |
---|
| 383 | //typedef CBlackListAwareComCreatorT<CComObjectCached<CFilterMapperSpy>, CFilterMapperSpy, &g_pszClassName> _ClassFactoryCreatorClass; // DECLARE_CLASSFACTORY override |
---|
| 384 | typedef CComCreator2<CBlackListAwareComCreatorT<CComObject<CFilterMapperSpy>, CFilterMapperSpy, &g_pszClassName>, CBlackListAwareComCreatorT<CComAggObject<CFilterMapperSpy>, CFilterMapperSpy, &g_pszClassName> > _CreatorClass; // DECLARE_AGGREGATABLE override |
---|
| 385 | |
---|
| 386 | public: |
---|
| 387 | // CFilterMapperSpy |
---|
| 388 | }; |
---|
| 389 | |
---|
| 390 | __declspec(selectany) LPCTSTR CFilterMapperSpy::g_pszClassName = _T("CFilterMapperSpy"); |
---|
| 391 | |
---|
| 392 | OBJECT_ENTRY_AUTO(__uuidof(FilterMapperSpy), CFilterMapperSpy) |
---|
| 393 | |
---|