source: trunk/DirectShowSpy/SystemDeviceEnumeratorSpy.h @ 267

Last change on this file since 267 was 267, checked in by roman, 10 years ago

Updated source code/copyright notice

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