source: trunk/DirectShowSpy/SystemDeviceEnumeratorSpy.h @ 545

Last change on this file since 545 was 545, checked in by roman, 6 years ago

Added previously not included hooks; added IFilterMapper3 hook suppors; template library related updates; added FGT to replace ROT (to access services in particular) - work in progress; fixed class enumeration hook

  • Property svn:keywords set to Id
File size: 23.6 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2015
3// Created by Roman Ryltsov roman@alax.info, http://alax.info
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
7// allowed to freely re-use the portions of the code in other projects, commercial
8// or otherwise (provided that you don’t pretend that you wrote the original tool).
9//
10// Please keep in mind that DirectShowSpy is a developer tool, it is strongly recommended
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.
15
16#pragma once
17
18#include "rodshow.h"
19#include "Module_i.h"
20#include "Common.h"
21
22////////////////////////////////////////////////////////////
23// CSystemDeviceEnumeratorSpyT
24
25// NOTE: Original CLSID_SystemDeviceEnum does not support aggregation
26
27template <typename T, const CLSID* t_pSystemDeviceEnumeratorClassIdentifier>
28class ATL_NO_VTABLE CSystemDeviceEnumeratorSpyT :
29        public CComObjectRootEx<CComMultiThreadModel>,
30        //public CComCoClass<CSystemDeviceEnumeratorSpyT, &CLSID_SystemDeviceEnumeratorSpy>,
31        public CTransparentCoClassT<T, t_pSystemDeviceEnumeratorClassIdentifier>,
32        public IDispatchImpl<ISystemDeviceEnumeratorSpy>,
33        public ICreateDevEnum
34{
35        typedef CSystemDeviceEnumeratorSpyT<T, t_pSystemDeviceEnumeratorClassIdentifier> CSystemDeviceEnumeratorSpy;
36
37public:
38        //enum { IDR = IDR_SYSTEMDEVICEENUMERATORSPY };
39
40//DECLARE_REGISTRY_RESOURCEID(IDR)
41
42DECLARE_PROTECT_FINAL_CONSTRUCT()
43
44DECLARE_GET_CONTROLLING_UNKNOWN()
45
46DECLARE_QI_TRACE(CSystemDeviceEnumeratorSpyT)
47
48BEGIN_COM_MAP(CSystemDeviceEnumeratorSpyT)
49        COM_INTERFACE_ENTRY(ISystemDeviceEnumeratorSpy)
50        COM_INTERFACE_ENTRY(ICreateDevEnum)
51        COM_INTERFACE_ENTRY_FUNC(CLSID_SystemDeviceEnum, 0, QuerySystemDeviceEnumInterface)
52        //COM_INTERFACE_ENTRY(IDispatch)
53END_COM_MAP()
54
55public:
56
57        ////////////////////////////////////////////////////////
58        // CPropertyBag
59
60        class ATL_NO_VTABLE CPropertyBag :
61                public CComObjectRootEx<CComMultiThreadModelNoCS>,
62                public IPropertyBag,
63                public IPropertyBag2
64        {
65        public:
66
67        DECLARE_QI_TRACE(CPropertyBag)
68
69        BEGIN_COM_MAP(CPropertyBag)
70                COM_INTERFACE_ENTRY(IPropertyBag2)
71                COM_INTERFACE_ENTRY(IPropertyBag)
72        END_COM_MAP()
73
74        private:
75                CComPtr<IPropertyBag> m_pPropertyBag;
76                CComPtr<IPropertyBag2> m_pPropertyBag2;
77
78        public:
79        // CPropertyBag
80                CPropertyBag()
81                {
82                        _Z4_THIS();
83                }
84                ~CPropertyBag()
85                {
86                        _Z4_THIS();
87                }
88                VOID Initialize(IPropertyBag* pPropertyBag)
89                {
90                        _A(pPropertyBag);
91                        _A(!m_pPropertyBag);
92                        m_pPropertyBag = pPropertyBag;
93                        m_pPropertyBag2 = CComQIPtr<IPropertyBag2>(pPropertyBag);
94                }
95
96        // IPropertyBag
97                STDMETHOD(Read)(LPCOLESTR pszPropertyName, VARIANT* pvValue, IErrorLog* pErrorLog) override
98                {
99                        _Z4(atlTraceCOM, 4, _T("pszPropertyName %s\n"), CString(pszPropertyName));
100                        _ATLTRY
101                        {
102                                HRESULT nResult = m_pPropertyBag->Read(pszPropertyName, pvValue, pErrorLog);
103                                #pragma region DevicePath Fix for Skype 6.0.0.126
104                                //if(nResult == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) && pszPropertyName && _wcsicmp(pszPropertyName, L"DevicePath") == 0 && pvValue)
105                                //{
106                                //      _Z4(atlTraceGeneral, 4, _T("nResult 0x%08X\n"), nResult);
107                                //      CComVariant vValue = L"\\\\?\\fake";
108                                //      _V(vValue.Detach(pvValue));
109                                //      nResult = S_OK;
110                                //}
111                                #pragma endregion
112                                if(SUCCEEDED(nResult))
113                                {
114                                        CString sValue = _T("???");
115                                        CComVariant vStringValue;
116                                        if(SUCCEEDED(vStringValue.ChangeType(VT_BSTR, pvValue)))
117                                                sValue = CString(vStringValue.bstrVal);
118                                        _Z4(atlTraceGeneral, 4, _T("nResult 0x%08X, pvValue->vt 0x%X, %s\n"), nResult, pvValue->vt, sValue);
119                                } else
120                                {
121                                        _Z4(atlTraceGeneral, 4, _T("nResult 0x%08X\n"), nResult);
122                                }
123                                return nResult;
124                        }
125                        _ATLCATCH(Exception)
126                        {
127                                _C(Exception);
128                        }
129                        return S_OK;
130                }
131                STDMETHOD(Write)(LPCOLESTR pszPropertyName, VARIANT* pvValue) override
132                {
133                        _Z4(atlTraceCOM, 4, _T("pszPropertyName %s, pvValue->vt 0x%X\n"), CString(pszPropertyName), pvValue->vt);
134                        _ATLTRY
135                        {
136                                const HRESULT nResult = m_pPropertyBag->Write(pszPropertyName, pvValue);
137                                _Z4(atlTraceGeneral, 4, _T("nResult 0x%08X\n"), nResult);
138                                return nResult;
139                        }
140                        _ATLCATCH(Exception)
141                        {
142                                _C(Exception);
143                        }
144                        return S_OK;
145                }
146
147        // IPropertyBag2
148                STDMETHOD(Read)(ULONG cProperties, PROPBAG2 *pPropBag, IErrorLog *pErrLog, VARIANT *pvarValue, HRESULT *phrError) override
149                {
150                        _Z4(atlTraceCOM, 4, _T("...\n"));
151                        _ATLTRY
152                        {
153                                const HRESULT nResult = m_pPropertyBag2->Read(cProperties, pPropBag, pErrLog, pvarValue, phrError);
154                                _Z4(atlTraceGeneral, 4, _T("nResult 0x%08X\n"), nResult);
155                                return nResult;
156                        }
157                        _ATLCATCH(Exception)
158                        {
159                                _C(Exception);
160                        }
161                        return S_OK;
162                }
163                STDMETHOD(Write)(ULONG cProperties, PROPBAG2 *pPropBag, VARIANT *pvarValue) override
164                {
165                        _Z4(atlTraceCOM, 4, _T("...\n"));
166                        _ATLTRY
167                        {
168                                const HRESULT nResult = m_pPropertyBag2->Write(cProperties, pPropBag, pvarValue);
169                                _Z4(atlTraceGeneral, 4, _T("nResult 0x%08X\n"), nResult);
170                                return nResult;
171                        }
172                        _ATLCATCH(Exception)
173                        {
174                                _C(Exception);
175                        }
176                        return S_OK;
177                }
178                STDMETHOD(CountProperties)(ULONG *pcProperties) override
179                {
180                        _Z4(atlTraceCOM, 4, _T("...\n"));
181                        _ATLTRY
182                        {
183                                const HRESULT nResult = m_pPropertyBag2->CountProperties(pcProperties);
184                                _Z4(atlTraceGeneral, 4, _T("nResult 0x%08X\n"), nResult);
185                                return nResult;
186                        }
187                        _ATLCATCH(Exception)
188                        {
189                                _C(Exception);
190                        }
191                        return S_OK;
192                }
193                STDMETHOD(GetPropertyInfo)(ULONG iProperty, ULONG cProperties, PROPBAG2* pPropBag, ULONG *pcProperties) override
194                {
195                        _Z4(atlTraceCOM, 4, _T("...\n"));
196                        _ATLTRY
197                        {
198                                const HRESULT nResult = m_pPropertyBag2->GetPropertyInfo(iProperty, cProperties, pPropBag, pcProperties);
199                                _Z4(atlTraceGeneral, 4, _T("nResult 0x%08X\n"), nResult);
200                                return nResult;
201                        }
202                        _ATLCATCH(Exception)
203                        {
204                                _C(Exception);
205                        }
206                        return S_OK;
207                }
208                STDMETHOD(LoadObject)(LPCOLESTR pstrName, DWORD dwHint, IUnknown *pUnkObject, IErrorLog *pErrLog) override
209                {
210                        _Z4(atlTraceCOM, 4, _T("...\n"));
211                        _ATLTRY
212                        {
213                                const HRESULT nResult = m_pPropertyBag2->LoadObject(pstrName, dwHint, pUnkObject, pErrLog);
214                                _Z4(atlTraceGeneral, 4, _T("nResult 0x%08X\n"), nResult);
215                                return nResult;
216                        }
217                        _ATLCATCH(Exception)
218                        {
219                                _C(Exception);
220                        }
221                        return S_OK;
222                }
223        };
224
225        ////////////////////////////////////////////////////////
226        // CMoniker
227
228        class ATL_NO_VTABLE CMoniker :
229                public CComObjectRootEx<CComMultiThreadModelNoCS>,
230                public IMoniker
231        {
232        public:
233
234        DECLARE_QI_TRACE(CMoniker)
235
236        BEGIN_COM_MAP(CMoniker)
237                COM_INTERFACE_ENTRY(IMoniker)
238                COM_INTERFACE_ENTRY(IPersistStream)
239                COM_INTERFACE_ENTRY(IPersist)
240        END_COM_MAP()
241
242        private:
243                CComPtr<IMoniker> m_pMoniker;
244
245        public:
246        // CMoniker
247                CMoniker()
248                {
249                        _Z4_THIS();
250                }
251                ~CMoniker()
252                {
253                        _Z4_THIS();
254                }
255                VOID Initialize(IMoniker* pMoniker)
256                {
257                        _A(pMoniker);
258                        _A(!m_pMoniker);
259                        m_pMoniker = pMoniker;
260                }
261
262        // IPersist
263                STDMETHOD(GetClassID)(CLSID* pClassIdentifier) override
264                {
265                        _Z4(atlTraceCOM, 4, _T("...\n"));
266                        return m_pMoniker->GetClassID(pClassIdentifier);
267                }
268
269    // IPersistStream
270                STDMETHOD(IsDirty)() override
271                {
272                        _Z4(atlTraceCOM, 4, _T("...\n"));
273                        return m_pMoniker->IsDirty();
274                }
275                STDMETHOD(Load)(IStream* pStream) override
276                {
277                        _Z4(atlTraceCOM, 4, _T("...\n"));
278                        return m_pMoniker->Load(pStream);
279                }
280                STDMETHOD(Save)(IStream* pStream, BOOL bClearDirty) override
281                {
282                        _Z4(atlTraceCOM, 4, _T("...\n"));
283                        return m_pMoniker->Save(pStream, bClearDirty);
284                }
285                STDMETHOD(GetSizeMax)(ULARGE_INTEGER* pnMaximalSize) override
286                {
287                        _Z4(atlTraceCOM, 4, _T("...\n"));
288                        return m_pMoniker->GetSizeMax(pnMaximalSize);
289                }
290
291        // IMoniker
292                STDMETHOD(BindToObject)(IBindCtx* pBindCtx, IMoniker* pLeftMoniker, REFIID InterfaceIdentifier, VOID** ppvObject) override
293                {
294                        _Z4(atlTraceCOM, 4, _T("pBindCtx 0x%p, pLeftMoniker 0x%p, InterfaceIdentifier %ls\n"), pBindCtx, pLeftMoniker, _PersistHelper::StringFromInterfaceIdentifier(InterfaceIdentifier));
295                        _ATLTRY
296                        {
297                                return m_pMoniker->BindToObject(pBindCtx, pLeftMoniker, InterfaceIdentifier, ppvObject);
298                        }
299                        _ATLCATCH(Exception)
300                        {
301                                _C(Exception);
302                        }
303                        return S_OK;
304                }
305                STDMETHOD(BindToStorage)(IBindCtx* pBindCtx, IMoniker* pLeftMoniker, REFIID InterfaceIdentifier, VOID** ppvObject) override
306                {
307                        _Z4(atlTraceCOM, 4, _T("pBindCtx 0x%p, pLeftMoniker 0x%p, InterfaceIdentifier %ls\n"), pBindCtx, pLeftMoniker, _PersistHelper::StringFromInterfaceIdentifier(InterfaceIdentifier));
308                        _ATLTRY
309                        {
310                                const HRESULT nResult = m_pMoniker->BindToStorage(pBindCtx, pLeftMoniker, InterfaceIdentifier, ppvObject);
311                                if(SUCCEEDED(nResult) && *ppvObject)
312                                {
313                                        if(InterfaceIdentifier == __uuidof(IPropertyBag) || InterfaceIdentifier == __uuidof(IPropertyBag2))
314                                        {
315                                                CComPtr<IPropertyBag>& pPropertyBag = reinterpret_cast<CComPtr<IPropertyBag>&>(*ppvObject);
316                                                CObjectPtr<CPropertyBag> pPropertyBagWrapper;
317                                                pPropertyBagWrapper.Construct()->Initialize(pPropertyBag);
318                                                pPropertyBag = pPropertyBagWrapper;
319                                        }
320                                }
321                                return nResult;
322                        }
323                        _ATLCATCH(Exception)
324                        {
325                                _C(Exception);
326                        }
327                        return S_OK;
328                }
329                STDMETHOD(Reduce)(IBindCtx* pBindCtx, DWORD nDepth, IMoniker** ppLeftMoniker, IMoniker** ppReducedMoniker) override
330                {
331                        _Z4(atlTraceCOM, 4, _T("...\n"));
332                        _ATLTRY
333                        {
334                                return m_pMoniker->Reduce(pBindCtx, nDepth, ppLeftMoniker, ppReducedMoniker);
335                        }
336                        _ATLCATCH(Exception)
337                        {
338                                _C(Exception);
339                        }
340                        return S_OK;
341                }
342                STDMETHOD(ComposeWith)(IMoniker* pRightMoniker, BOOL bOnlyIfNotGeneric, IMoniker** ppCompositeMoniker) override
343                {
344                        _Z4(atlTraceCOM, 4, _T("...\n"));
345                        _ATLTRY
346                        {
347                                return m_pMoniker->ComposeWith(pRightMoniker, bOnlyIfNotGeneric, ppCompositeMoniker);
348                        }
349                        _ATLCATCH(Exception)
350                        {
351                                _C(Exception);
352                        }
353                        return S_OK;
354                }
355                STDMETHOD(Enum)(BOOL bForward, IEnumMoniker** ppEnumMoniker) override
356                {
357                        _Z4(atlTraceCOM, 4, _T("bForward %d\n"), bForward);
358                        _ATLTRY
359                        {
360                                return m_pMoniker->Enum(bForward, ppEnumMoniker);
361                        }
362                        _ATLCATCH(Exception)
363                        {
364                                _C(Exception);
365                        }
366                        return S_OK;
367                }
368                STDMETHOD(IsEqual)(IMoniker* pMoniker) override
369                {
370                        _Z4(atlTraceCOM, 4, _T("...\n"));
371                        _ATLTRY
372                        {
373                                return m_pMoniker->IsEqual(pMoniker);
374                        }
375                        _ATLCATCH(Exception)
376                        {
377                                _C(Exception);
378                        }
379                        return S_OK;
380                }
381                STDMETHOD(Hash)(DWORD* pnHashValue) override
382                {
383                        _Z4(atlTraceCOM, 4, _T("...\n"));
384                        _ATLTRY
385                        {
386                                return m_pMoniker->Hash(pnHashValue);
387                        }
388                        _ATLCATCH(Exception)
389                        {
390                                _C(Exception);
391                        }
392                        return S_OK;
393                }
394                STDMETHOD(IsRunning)(IBindCtx* pBindCtx, IMoniker* pLeftMoniker, IMoniker* pNewlyRunning) override
395                {
396                        _Z4(atlTraceCOM, 4, _T("...\n"));
397                        _ATLTRY
398                        {
399                                return m_pMoniker->IsRunning(pBindCtx, pLeftMoniker, pNewlyRunning);
400                        }
401                        _ATLCATCH(Exception)
402                        {
403                                _C(Exception);
404                        }
405                        return S_OK;
406                }
407                STDMETHOD(GetTimeOfLastChange)(IBindCtx* pBindCtx, IMoniker* pLeftMoniker, FILETIME* pFileTime) override
408                {
409                        _Z4(atlTraceCOM, 4, _T("...\n"));
410                        _ATLTRY
411                        {
412                                return m_pMoniker->GetTimeOfLastChange(pBindCtx, pLeftMoniker, pFileTime);
413                        }
414                        _ATLCATCH(Exception)
415                        {
416                                _C(Exception);
417                        }
418                        return S_OK;
419                }
420                STDMETHOD(Inverse)(IMoniker** ppMoniker) override
421                {
422                        _Z4(atlTraceCOM, 4, _T("...\n"));
423                        _ATLTRY
424                        {
425                                return m_pMoniker->Inverse(ppMoniker);
426                        }
427                        _ATLCATCH(Exception)
428                        {
429                                _C(Exception);
430                        }
431                        return S_OK;
432                }
433                STDMETHOD(CommonPrefixWith)(IMoniker* pMoniker, IMoniker** ppPrefixMoniker) override
434                {
435                        _Z4(atlTraceCOM, 4, _T("...\n"));
436                        _ATLTRY
437                        {
438                                return m_pMoniker->CommonPrefixWith(pMoniker, ppPrefixMoniker);
439                        }
440                        _ATLCATCH(Exception)
441                        {
442                                _C(Exception);
443                        }
444                        return S_OK;
445                }
446                STDMETHOD(RelativePathTo)(IMoniker* pMoniker, IMoniker** ppRelativeMoniker) override
447                {
448                        _Z4(atlTraceCOM, 4, _T("...\n"));
449                        _ATLTRY
450                        {
451                                return m_pMoniker->RelativePathTo(pMoniker, ppRelativeMoniker);
452                        }
453                        _ATLCATCH(Exception)
454                        {
455                                _C(Exception);
456                        }
457                        return S_OK;
458                }
459                STDMETHOD(GetDisplayName)(IBindCtx* pBindCtx, IMoniker* pLeftMoniker, LPOLESTR* ppszDisplayName) override
460                {
461                        _Z4(atlTraceCOM, 4, _T("pBindCtx 0x%p, pLeftMoniker 0x%p\n"), pBindCtx, pLeftMoniker);
462                        _ATLTRY
463                        {
464                                const HRESULT nResult = m_pMoniker->GetDisplayName(pBindCtx, pLeftMoniker, ppszDisplayName);
465                                if(SUCCEEDED(nResult))
466                                        _Z4(atlTraceGeneral, 4, _T("nResult 0x%08X, *ppszDisplayName %s\n"), nResult, CString(*ppszDisplayName));
467                                else
468                                        _Z4(atlTraceGeneral, 4, _T("nResult 0x%08X\n"), nResult);
469                                return nResult;
470                        }
471                        _ATLCATCH(Exception)
472                        {
473                                _C(Exception);
474                        }
475                        return S_OK;
476                }
477                STDMETHOD(ParseDisplayName)(IBindCtx* pBindCtx, IMoniker* pLeftMoniker, LPOLESTR pszDisplayName, ULONG* pnEatenLength, IMoniker** ppOutputMoniker) override
478                {
479                        _Z4(atlTraceCOM, 4, _T("pBindCtx 0x%p, pLeftMoniker 0x%p, pszDisplayName %s\n"), pBindCtx, pLeftMoniker, CString(pszDisplayName));
480                        _ATLTRY
481                        {
482                                return m_pMoniker->ParseDisplayName(pBindCtx, pLeftMoniker, pszDisplayName, pnEatenLength, ppOutputMoniker);
483                        }
484                        _ATLCATCH(Exception)
485                        {
486                                _C(Exception);
487                        }
488                        return S_OK;
489                }
490                STDMETHOD(IsSystemMoniker)(DWORD* pnSystemMonikerType) override
491                {
492                        _Z4(atlTraceCOM, 4, _T("...\n"));
493                        _ATLTRY
494                        {
495                                return m_pMoniker->IsSystemMoniker(pnSystemMonikerType);
496                        }
497                        _ATLCATCH(Exception)
498                        {
499                                _C(Exception);
500                        }
501                        return S_OK;
502                }
503        };
504
505        ////////////////////////////////////////////////////////
506        // CEnumMoniker
507
508        class ATL_NO_VTABLE CEnumMoniker :
509                public CComObjectRootEx<CComMultiThreadModelNoCS>,
510                public IEnumMoniker
511        {
512        public:
513
514        DECLARE_QI_TRACE(CEnumMoniker)
515
516        BEGIN_COM_MAP(CEnumMoniker)
517                COM_INTERFACE_ENTRY(IEnumMoniker)
518        END_COM_MAP()
519
520        private:
521                CComPtr<IEnumMoniker> m_pEnumMoniker;
522
523        public:
524        // CEnumMoniker
525                CEnumMoniker()
526                {
527                        _Z4_THIS();
528                }
529                ~CEnumMoniker()
530                {
531                        _Z4_THIS();
532                }
533                VOID Initialize(IEnumMoniker* pEnumMoniker)
534                {
535                        _A(pEnumMoniker);
536                        _A(!m_pEnumMoniker);
537                        m_pEnumMoniker = pEnumMoniker;
538                }
539
540        // IEnumMoniker
541                STDMETHOD(Next)(ULONG nElementCount, IMoniker** ppMoniker, ULONG* pnFetchElementCount) override
542                {
543                        _Z4(atlTraceCOM, 4, _T("nElementCount %d\n"), nElementCount);
544                        _ATLTRY
545                        {
546                                const HRESULT nNextResult = m_pEnumMoniker->Next(nElementCount, ppMoniker, pnFetchElementCount);
547                                CRoArrayT<CString> Array;
548                                if(pnFetchElementCount)
549                                        Array.Add(AtlFormatString(_T("*pnFetchElementCount %d"), *pnFetchElementCount));
550                                _Z4(atlTraceGeneral, 4, _T("nNextResult 0x%08X, %s\n"), nNextResult, _StringHelper::Join(Array, _T(", ")));
551                                if(SUCCEEDED(nNextResult))
552                                {
553                                        ULONG nFetchedElementCount = nElementCount;
554                                        if(nNextResult != S_OK && pnFetchElementCount)
555                                                nFetchedElementCount = *pnFetchElementCount;
556                                        for(ULONG nIndex = 0; nIndex < nFetchedElementCount; nIndex++)
557                                        {
558                                                CComPtr<IMoniker>& pMoniker = reinterpret_cast<CComPtr<IMoniker>&>(ppMoniker[nIndex]);
559                                                if(!pMoniker)
560                                                        break;
561                                                CObjectPtr<CMoniker> pMonikerWrapper;
562                                                pMonikerWrapper.Construct()->Initialize(pMoniker);
563                                                pMoniker = pMonikerWrapper;
564                                        }
565                                }
566                                return nNextResult;
567                        }
568                        _ATLCATCH(Exception)
569                        {
570                                _C(Exception);
571                        }
572                        return S_OK;
573                }
574                STDMETHOD(Skip)(ULONG nElementCount) override
575                {
576                        _Z4(atlTraceCOM, 4, _T("nElementCount %d\n"), nElementCount);
577                        _ATLTRY
578                        {
579                                return m_pEnumMoniker->Skip(nElementCount);
580                        }
581                        _ATLCATCH(Exception)
582                        {
583                                _C(Exception);
584                        }
585                        return S_OK;
586                }
587                STDMETHOD(Reset)() override
588                {
589                        _Z4(atlTraceCOM, 4, _T("...\n"));
590                        _ATLTRY
591                        {
592                                return m_pEnumMoniker->Reset();
593                        }
594                        _ATLCATCH(Exception)
595                        {
596                                _C(Exception);
597                        }
598                        return S_OK;
599                }
600                STDMETHOD(Clone)(IEnumMoniker** ppEnumMoniker) override
601                {
602                        _Z4(atlTraceCOM, 4, _T("...\n"));
603                        _ATLTRY
604                        {
605                                __C(m_pEnumMoniker->Clone(ppEnumMoniker));
606                                CComPtr<IEnumMoniker>& pEnumMoniker = reinterpret_cast<CComPtr<IEnumMoniker>&>(*ppEnumMoniker);
607                                _A(pEnumMoniker);
608                                CObjectPtr<CEnumMoniker> pEnumMonikerWrapper;
609                                pEnumMonikerWrapper.Construct()->Initialize(pEnumMoniker);
610                                pEnumMoniker = pEnumMonikerWrapper;
611                        }
612                        _ATLCATCH(Exception)
613                        {
614                                _C(Exception);
615                        }
616                        return S_OK;
617                }
618        };
619
620private:
621        HINSTANCE m_hDevEnumModule;
622        CComPtr<IUnknown> m_pSystemDeviceEnum;
623        CComPtr<ICreateDevEnum> m_pCreateDevEnum;
624
625        HRESULT QuerySystemDeviceEnumInterface(REFIID InterfaceIdentifier, VOID** ppvObject)
626        {
627                _A(InterfaceIdentifier == CLSID_SystemDeviceEnum);
628                _A(ppvObject);
629                *ppvObject = CComPtr<IUnknown>(m_pSystemDeviceEnum).Detach();
630                return S_OK;
631        }
632        static HRESULT WINAPI QuerySystemDeviceEnumInterface(VOID* pvInstance, REFIID InterfaceIdentifier, VOID** ppvObject, DWORD_PTR)
633        {
634                return ((CSystemDeviceEnumeratorSpy*) pvInstance)->QuerySystemDeviceEnumInterface(InterfaceIdentifier, ppvObject);
635        }
636
637public:
638// CSystemDeviceEnumeratorSpyT
639        static LPCTSTR GetOriginalLibraryName()
640        {
641                return _T("devenum.dll");
642        }
643        static CString GetObjectFriendlyName()
644        {
645                return _StringHelper::GetLine(T::IDR, 2);
646        }
647        static HRESULT WINAPI UpdateRegistry(BOOL bRegister)
648        {
649                _Z2(atlTraceRegistrar, 2, _T("bRegister %d\n"), bRegister);
650                _ATLTRY
651                {
652                        TreatAsUpdateRegistryFromResource<T>(*t_pSystemDeviceEnumeratorClassIdentifier, bRegister);
653                }
654                _ATLCATCH(Exception)
655                {
656                        _C(Exception);
657                }
658                return S_OK;
659        }
660        CSystemDeviceEnumeratorSpyT() :
661                m_hDevEnumModule(NULL)
662        {
663                _Z4_THIS();
664        }
665        ~CSystemDeviceEnumeratorSpyT()
666        {
667                _Z4_THIS();
668        }
669        HRESULT FinalConstruct()
670        {
671                _ATLTRY
672                {
673                        TCHAR pszPath[MAX_PATH] = { 0 };
674                        _W(GetModuleFileName(NULL, pszPath, DIM(pszPath)));
675                        _Z4(atlTraceRefcount, 4, _T("pszPath \"%s\", this 0x%p, m_dwRef %d\n"), pszPath, this, m_dwRef);
676                        const HINSTANCE hModule = CoLoadLibrary(const_cast<LPOLESTR>((LPCOLESTR) CT2COLE(GetOriginalLibraryName())), TRUE);
677                        _ATLTRY
678                        {
679                                typedef HRESULT (WINAPI *DLLGETCLASSOBJECT)(REFCLSID, REFIID, VOID**);
680                                DLLGETCLASSOBJECT DllGetClassObject = (DLLGETCLASSOBJECT) GetProcAddress(hModule, "DllGetClassObject");
681                                __E(DllGetClassObject);
682                                CComPtr<IClassFactory> pClassFactory;
683                                __C(DllGetClassObject(*t_pSystemDeviceEnumeratorClassIdentifier, __uuidof(IClassFactory), (VOID**) &pClassFactory));
684                                _A(pClassFactory);
685                                CComPtr<IUnknown> pUnknown;
686                                __C(pClassFactory->CreateInstance(NULL, __uuidof(IUnknown), (VOID**) &pUnknown));
687                                __D(pUnknown, E_NOINTERFACE);
688                                CComPtr<IUnknown> pSystemDeviceEnum;
689                                __C(pUnknown->QueryInterface(CLSID_SystemDeviceEnum, (VOID**) &pSystemDeviceEnum));
690                                const CComQIPtr<ICreateDevEnum> pCreateDevEnum = pUnknown;
691                                __D(pCreateDevEnum, E_NOINTERFACE);
692                                m_pSystemDeviceEnum = pSystemDeviceEnum;
693                                m_pCreateDevEnum = pCreateDevEnum;
694                        }
695                        _ATLCATCHALL()
696                        {
697                                CoFreeLibrary(hModule);
698                                _ATLRETHROW;
699                        }
700                        _A(!m_hDevEnumModule);
701                        m_hDevEnumModule = hModule;
702                }
703                _ATLCATCH(Exception)
704                {
705                        _C(Exception);
706                }
707                return S_OK;
708        }
709        VOID FinalRelease()
710        {
711                _Z5(atlTraceRefcount, 5, _T("m_dwRef 0x%X\n"), m_dwRef);
712                m_pSystemDeviceEnum.Release();
713                m_pCreateDevEnum.Release();
714                if(m_hDevEnumModule)
715                {
716                        CoFreeLibrary(m_hDevEnumModule);
717                        m_hDevEnumModule = NULL;
718                }
719        }
720        static CString FormatDeviceCategory(const GUID& DeviceCategory)
721        {
722                static const struct 
723                { 
724                        const GUID* pIdentifier; 
725                        LPCSTR pszName; 
726                } g_pMap[] = 
727                {
728                        #define A(x) { &x, #x },
729                        A(CLSID_VideoInputDeviceCategory)
730                        A(CLSID_LegacyAmFilterCategory)
731                        A(CLSID_VideoCompressorCategory)
732                        A(CLSID_AudioCompressorCategory)
733                        A(CLSID_AudioInputDeviceCategory)
734                        A(CLSID_AudioRendererCategory)
735                        A(CLSID_MidiRendererCategory)
736                        A(CLSID_TransmitCategory)
737                        A(CLSID_DeviceControlCategory)
738                        A(CLSID_ActiveMovieCategories)
739                        A(CLSID_DVDHWDecodersCategory)
740                        A(CLSID_MediaEncoderCategory)
741                        A(CLSID_MediaMultiplexerCategory)
742                        #undef A
743                };
744                for(auto&& Item: g_pMap)
745                        if(*Item.pIdentifier == DeviceCategory)
746                                return CString(Item.pszName);
747                return CString(_PersistHelper::StringFromIdentifier(DeviceCategory));
748        }
749
750// ISystemDeviceEnumeratorSpy
751
752// ICreateDevEnum
753        STDMETHOD(CreateClassEnumerator)(REFCLSID DeviceCategory, IEnumMoniker** ppEnumMoniker, DWORD nFlags) override
754        {
755                _Z4(atlTraceCOM, 4, _T("DeviceCategory %s, nFlags 0x%X\n"), FormatDeviceCategory(DeviceCategory), nFlags);
756                _ATLTRY
757                {
758                        const HRESULT nCreateClassEnumeratorResult = m_pCreateDevEnum->CreateClassEnumerator(DeviceCategory, ppEnumMoniker, nFlags);
759                        __C(nCreateClassEnumeratorResult);
760                        _D(nCreateClassEnumeratorResult == S_OK, nCreateClassEnumeratorResult);
761                        CComPtr<IEnumMoniker>& pEnumMoniker = reinterpret_cast<CComPtr<IEnumMoniker>&>(*ppEnumMoniker);
762                        if(pEnumMoniker)
763                        {
764                                #pragma region Trace Moniker
765                                __C(pEnumMoniker->Reset());
766                                for(; ; )
767                                {
768                                        CComPtr<IMoniker> pMoniker;
769                                        ULONG nElementCount;
770                                        if(pEnumMoniker->Next(1, &pMoniker, &nElementCount) != S_OK)
771                                                break;
772                                        _Z4(atlTraceGeneral, 4, _T("pMoniker %ls\n"), _FilterGraphHelper::GetMonikerDisplayName(pMoniker));
773                                        CComPtr<IBindCtx> pBindCtx;
774                                        __C(CreateBindCtx(0, &pBindCtx));
775                                        CComPtr<IPropertyBag> pPropertyBag;
776                                        __C(pMoniker->BindToStorage(pBindCtx, NULL, __uuidof(IPropertyBag), (VOID**) &pPropertyBag));
777                                        const CStringW sFriendlyName = _FilterGraphHelper::ReadPropertyBagString(pPropertyBag, OLESTR("FriendlyName"));
778                                        const CStringW sDescription = _FilterGraphHelper::ReadPropertyBagString(pPropertyBag, OLESTR("Description"));
779                                        const CStringW sDevicePath = _FilterGraphHelper::ReadPropertyBagString(pPropertyBag, OLESTR("DevicePath"));
780                                        _Z4(atlTraceCOM, 4, _T("sFriendlyName \"%ls\", sDescription \"%ls\", sDevicePath \"%ls\"\n"), sFriendlyName, sDescription, sDevicePath);
781                                }
782                                __C(pEnumMoniker->Reset());
783                                #pragma endregion
784                                CObjectPtr<CEnumMoniker> pEnumMonikerWrapper;
785                                pEnumMonikerWrapper.Construct()->Initialize(pEnumMoniker);
786                                pEnumMoniker = pEnumMonikerWrapper;
787                        }
788                }
789                _ATLCATCH(Exception)
790                {
791                        _C(Exception);
792                }
793                return S_OK;
794        }
795};
796
797////////////////////////////////////////////////////////////
798// CSystemDeviceEnumeratorSpy
799
800class ATL_NO_VTABLE CSystemDeviceEnumeratorSpy :
801        public CSystemDeviceEnumeratorSpyT<CSystemDeviceEnumeratorSpy, &CLSID_SystemDeviceEnum>,
802        public CComCoClass<CSystemDeviceEnumeratorSpy, &CLSID_SystemDeviceEnumeratorSpy>
803{
804public:
805        enum { IDR = IDR_SYSTEMDEVICEENUMERATORSPY };
806
807private:
808        static LPCTSTR g_pszClassName;
809
810public:
811        //typedef CBlackListAwareComCreatorT<CComObjectCached<CSystemDeviceEnumeratorSpy>, CSystemDeviceEnumeratorSpy, &g_pszClassName> _ClassFactoryCreatorClass; // DECLARE_CLASSFACTORY override
812        typedef CComCreator2<CBlackListAwareComCreatorT<CComObject<CSystemDeviceEnumeratorSpy>, CSystemDeviceEnumeratorSpy, &g_pszClassName>, CBlackListAwareComCreatorT<CComAggObject<CSystemDeviceEnumeratorSpy>, CSystemDeviceEnumeratorSpy, &g_pszClassName> > _CreatorClass; // DECLARE_AGGREGATABLE override
813
814public:
815// CSystemDeviceEnumeratorSpy
816};
817
818__declspec(selectany) LPCTSTR CSystemDeviceEnumeratorSpy::g_pszClassName = _T("CSystemDeviceEnumeratorSpy");
819
820OBJECT_ENTRY_AUTO(__uuidof(SystemDeviceEnumeratorSpy), CSystemDeviceEnumeratorSpy)
Note: See TracBrowser for help on using the repository browser.