source: trunk/DirectShowSpy/SystemDeviceEnumeratorSpy.h @ 276

Last change on this file since 276 was 276, checked in by roman, 9 years ago

Updated header (on use, applicability, redistribution)

  • Property svn:keywords set to Id
File size: 23.7 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2014
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 "DirectShowSpy_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(CSystemDeviceEnumeratorSpy)
47
48BEGIN_COM_MAP(CSystemDeviceEnumeratorSpy)
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(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
83                }
84                ~CPropertyBag()
85                {
86                        _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), 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) throw()
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) throw()
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) throw()
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) throw()
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) throw()
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) throw()
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) throw()
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(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
250                }
251                ~CMoniker()
252                {
253                        _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), 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) throw()
264                {
265                        _Z4(atlTraceCOM, 4, _T("...\n"));
266                        return m_pMoniker->GetClassID(pClassIdentifier);
267                }
268
269    // IPersistStream
270                STDMETHOD(IsDirty)() throw()
271                {
272                        _Z4(atlTraceCOM, 4, _T("...\n"));
273                        return m_pMoniker->IsDirty();
274                }
275                STDMETHOD(Load)(IStream* pStream) throw()
276                {
277                        _Z4(atlTraceCOM, 4, _T("...\n"));
278                        return m_pMoniker->Load(pStream);
279                }
280                STDMETHOD(Save)(IStream* pStream, BOOL bClearDirty) throw()
281                {
282                        _Z4(atlTraceCOM, 4, _T("...\n"));
283                        return m_pMoniker->Save(pStream, bClearDirty);
284                }
285                STDMETHOD(GetSizeMax)(ULARGE_INTEGER* pnMaximalSize) throw()
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) throw()
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) throw()
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) throw()
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) throw()
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) throw()
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) throw()
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) throw()
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) throw()
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) throw()
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) throw()
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) throw()
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) throw()
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) throw()
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) throw()
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) throw()
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(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
528                }
529                ~CEnumMoniker()
530                {
531                        _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), 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* pnFetchedElementCount) throw()
542                {
543                        _Z4(atlTraceCOM, 4, _T("nElementCount %d\n"), nElementCount);
544                        _ATLTRY
545                        {
546                                const HRESULT nNextResult = m_pEnumMoniker->Next(nElementCount, ppMoniker, pnFetchedElementCount);
547                                _Z4(atlTraceGeneral, 4, _T("nNextResult 0x%08x, *pnFetchedElementCount %s\n"), nNextResult, pnFetchedElementCount ? (LPCTSTR) AtlFormatString(_T("%d"), *pnFetchedElementCount) : _T("(null)"));
548                                if(SUCCEEDED(nNextResult))
549                                {
550                                        ULONG nFetchedElementCount = nElementCount;
551                                        if(nNextResult != S_OK && pnFetchedElementCount)
552                                                nFetchedElementCount = *pnFetchedElementCount;
553                                        for(SIZE_T nIndex = 0; nIndex < nFetchedElementCount; nIndex++)
554                                        {
555                                                CComPtr<IMoniker>& pMoniker = reinterpret_cast<CComPtr<IMoniker>&>(ppMoniker[nIndex]);
556                                                if(!pMoniker)
557                                                        break;
558                                                CObjectPtr<CMoniker> pMonikerWrapper;
559                                                pMonikerWrapper.Construct()->Initialize(pMoniker);
560                                                pMoniker = pMonikerWrapper;
561                                        }
562                                }
563                                return nNextResult;
564                        }
565                        _ATLCATCH(Exception)
566                        {
567                                _C(Exception);
568                        }
569                        return S_OK;
570                }
571                STDMETHOD(Skip)(ULONG nElementCount) throw()
572                {
573                        _Z4(atlTraceCOM, 4, _T("nElementCount %d\n"), nElementCount);
574                        _ATLTRY
575                        {
576                                return m_pEnumMoniker->Skip(nElementCount);
577                        }
578                        _ATLCATCH(Exception)
579                        {
580                                _C(Exception);
581                        }
582                        return S_OK;
583                }
584                STDMETHOD(Reset)() throw()
585                {
586                        _Z4(atlTraceCOM, 4, _T("...\n"));
587                        _ATLTRY
588                        {
589                                return m_pEnumMoniker->Reset();
590                        }
591                        _ATLCATCH(Exception)
592                        {
593                                _C(Exception);
594                        }
595                        return S_OK;
596                }
597                STDMETHOD(Clone)(IEnumMoniker** ppEnumMoniker) throw()
598                {
599                        _Z4(atlTraceCOM, 4, _T("...\n"));
600                        _ATLTRY
601                        {
602                                __C(m_pEnumMoniker->Clone(ppEnumMoniker));
603                                CComPtr<IEnumMoniker>& pEnumMoniker = reinterpret_cast<CComPtr<IEnumMoniker>&>(*ppEnumMoniker);
604                                _A(pEnumMoniker);
605                                CObjectPtr<CEnumMoniker> pEnumMonikerWrapper;
606                                pEnumMonikerWrapper.Construct()->Initialize(pEnumMoniker);
607                                pEnumMoniker = pEnumMonikerWrapper;
608                        }
609                        _ATLCATCH(Exception)
610                        {
611                                _C(Exception);
612                        }
613                        return S_OK;
614                }
615        };
616
617private:
618        HINSTANCE m_hDevEnumModule;
619        CComPtr<IUnknown> m_pSystemDeviceEnum;
620        CComPtr<ICreateDevEnum> m_pCreateDevEnum;
621
622        HRESULT QuerySystemDeviceEnumInterface(REFIID InterfaceIdentifier, VOID** ppvObject)
623        {
624                _A(InterfaceIdentifier == CLSID_SystemDeviceEnum);
625                _A(ppvObject);
626                *ppvObject = CComPtr<IUnknown>(m_pSystemDeviceEnum).Detach();
627                return S_OK;
628        }
629        static HRESULT WINAPI QuerySystemDeviceEnumInterface(VOID* pvInstance, REFIID InterfaceIdentifier, VOID** ppvObject, DWORD)
630        {
631                return ((CSystemDeviceEnumeratorSpy*) pvInstance)->QuerySystemDeviceEnumInterface(InterfaceIdentifier, ppvObject);
632        }
633
634public:
635// CSystemDeviceEnumeratorSpyT
636        static LPCTSTR GetOriginalLibraryName() throw()
637        {
638                return _T("devenum.dll");
639        }
640        static CString GetObjectFriendlyName()
641        {
642                return _StringHelper::GetLine(T::IDR, 2);
643        }
644        static HRESULT WINAPI UpdateRegistry(BOOL bRegister) throw()
645        {
646                _Z2(atlTraceRegistrar, 2, _T("bRegister %d\n"), bRegister);
647                _ATLTRY
648                {
649                        TreatAsUpdateRegistryFromResource<T>(*t_pSystemDeviceEnumeratorClassIdentifier, bRegister);
650                }
651                _ATLCATCH(Exception)
652                {
653                        _C(Exception);
654                }
655                return S_OK;
656        }
657        CSystemDeviceEnumeratorSpyT() throw() :
658                m_hDevEnumModule(NULL)
659        {
660                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
661        }
662        ~CSystemDeviceEnumeratorSpyT() throw()
663        {
664                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
665        }
666        HRESULT FinalConstruct() throw()
667        {
668                _ATLTRY
669                {
670                        TCHAR pszPath[MAX_PATH] = { 0 };
671                        _W(GetModuleFileName(NULL, pszPath, DIM(pszPath)));
672                        _Z4(atlTraceRefcount, 4, _T("pszPath \"%s\", this 0x%08x, m_dwRef %d\n"), pszPath, this, m_dwRef);
673                        const HINSTANCE hModule = CoLoadLibrary(const_cast<LPOLESTR>((LPCOLESTR) CT2COLE(GetOriginalLibraryName())), TRUE);
674                        _ATLTRY
675                        {
676                                typedef HRESULT (WINAPI *DLLGETCLASSOBJECT)(REFCLSID, REFIID, VOID**);
677                                DLLGETCLASSOBJECT DllGetClassObject = (DLLGETCLASSOBJECT) GetProcAddress(hModule, "DllGetClassObject");
678                                __E(DllGetClassObject);
679                                CComPtr<IClassFactory> pClassFactory;
680                                __C(DllGetClassObject(*t_pSystemDeviceEnumeratorClassIdentifier, __uuidof(IClassFactory), (VOID**) &pClassFactory));
681                                _A(pClassFactory);
682                                CComPtr<IUnknown> pUnknown;
683                                __C(pClassFactory->CreateInstance(NULL, __uuidof(IUnknown), (VOID**) &pUnknown));
684                                __D(pUnknown, E_NOINTERFACE);
685                                CComPtr<IUnknown> pSystemDeviceEnum;
686                                __C(pUnknown->QueryInterface(CLSID_SystemDeviceEnum, (VOID**) &pSystemDeviceEnum));
687                                const CComQIPtr<ICreateDevEnum> pCreateDevEnum = pUnknown;
688                                __D(pCreateDevEnum, E_NOINTERFACE);
689                                m_pSystemDeviceEnum = pSystemDeviceEnum;
690                                m_pCreateDevEnum = pCreateDevEnum;
691                        }
692                        _ATLCATCHALL()
693                        {
694                                CoFreeLibrary(hModule);
695                                _ATLRETHROW;
696                        }
697                        _A(!m_hDevEnumModule);
698                        m_hDevEnumModule = hModule;
699                }
700                _ATLCATCH(Exception)
701                {
702                        _C(Exception);
703                }
704                return S_OK;
705        }
706        VOID FinalRelease() throw()
707        {
708                _Z5(atlTraceRefcount, 5, _T("m_dwRef 0x%x\n"), m_dwRef);
709                m_pSystemDeviceEnum = NULL;
710                m_pCreateDevEnum = NULL;
711                if(m_hDevEnumModule)
712                {
713                        CoFreeLibrary(m_hDevEnumModule);
714                        m_hDevEnumModule = NULL;
715                }
716        }
717        static CString FormatDeviceCategory(const GUID& DeviceCategory)
718        {
719                static const struct { const GUID* pIdentifier; LPCSTR pszName; } g_pMap[] = 
720                {
721                        #define A(x) { &x, #x },
722                        A(CLSID_VideoInputDeviceCategory)
723                        A(CLSID_LegacyAmFilterCategory)
724                        A(CLSID_VideoCompressorCategory)
725                        A(CLSID_AudioCompressorCategory)
726                        A(CLSID_AudioInputDeviceCategory)
727                        A(CLSID_AudioRendererCategory)
728                        A(CLSID_MidiRendererCategory)
729                        A(CLSID_TransmitCategory)
730                        A(CLSID_DeviceControlCategory)
731                        A(CLSID_ActiveMovieCategories)
732                        A(CLSID_DVDHWDecodersCategory)
733                        A(CLSID_MediaEncoderCategory)
734                        A(CLSID_MediaMultiplexerCategory)
735                        #undef A
736                };
737                for(SIZE_T nIndex = 0; nIndex < DIM(g_pMap); nIndex++)
738                        if(*g_pMap[nIndex].pIdentifier == DeviceCategory)
739                                return CString(g_pMap[nIndex].pszName);
740                return CString(_PersistHelper::StringFromIdentifier(DeviceCategory));
741        }
742
743// ISystemDeviceEnumeratorSpy
744
745// ICreateDevEnum
746        STDMETHOD(CreateClassEnumerator)(REFCLSID DeviceCategory, IEnumMoniker** ppEnumMoniker, DWORD nFlags) throw()
747        {
748                _Z4(atlTraceCOM, 4, _T("DeviceCategory %s, nFlags 0x%x\n"), FormatDeviceCategory(DeviceCategory), nFlags);
749                _ATLTRY
750                {
751                        __C(m_pCreateDevEnum->CreateClassEnumerator(DeviceCategory, ppEnumMoniker, nFlags));
752                        CComPtr<IEnumMoniker>& pEnumMoniker = reinterpret_cast<CComPtr<IEnumMoniker>&>(*ppEnumMoniker);
753                        if(pEnumMoniker)
754                        {
755                                #pragma region Trace Monikers
756                                __C(pEnumMoniker->Reset());
757                                CComPtr<IMoniker> pMoniker;
758                                while(pEnumMoniker->Next(1, &pMoniker, NULL) == S_OK)
759                                {
760                                        _Z4(atlTraceCOM, 4, _T("pMoniker %ls\n"), _FilterGraphHelper::GetMonikerDisplayName(pMoniker));
761                                        CComPtr<IBindCtx> pBindCtx;
762                                        __C(CreateBindCtx(0, &pBindCtx));
763                                        CComPtr<IPropertyBag> pPropertyBag;
764                                        __C(pMoniker->BindToStorage(pBindCtx, NULL, __uuidof(IPropertyBag), (VOID**) &pPropertyBag));
765                                        const CStringW sFriendlyName = _FilterGraphHelper::ReadPropertyBagString(pPropertyBag, OLESTR("FriendlyName"));
766                                        const CStringW sDescription = _FilterGraphHelper::ReadPropertyBagString(pPropertyBag, OLESTR("Description"));
767                                        const CStringW sDevicePath = _FilterGraphHelper::ReadPropertyBagString(pPropertyBag, OLESTR("DevicePath"));
768                                        _Z4(atlTraceCOM, 4, _T("sFriendlyName \"%ls\", sDescription \"%ls\", sDevicePath \"%ls\"\n"), sFriendlyName, sDescription, sDevicePath);
769                                        pMoniker.Release();
770                                }
771                                __C(pEnumMoniker->Reset());
772                                #pragma endregion
773                                CObjectPtr<CEnumMoniker> pEnumMonikerWrapper;
774                                pEnumMonikerWrapper.Construct()->Initialize(pEnumMoniker);
775                                pEnumMoniker = pEnumMonikerWrapper;
776                        }
777                }
778                _ATLCATCH(Exception)
779                {
780                        _C(Exception);
781                }
782                return S_OK;
783        }
784};
785
786////////////////////////////////////////////////////////////
787// CSystemDeviceEnumeratorSpy
788
789class ATL_NO_VTABLE CSystemDeviceEnumeratorSpy :
790        public CSystemDeviceEnumeratorSpyT<CSystemDeviceEnumeratorSpy, &CLSID_SystemDeviceEnum>,
791        public CComCoClass<CSystemDeviceEnumeratorSpy, &CLSID_SystemDeviceEnumeratorSpy>
792{
793public:
794        enum { IDR = IDR_SYSTEMDEVICEENUMERATORSPY };
795
796private:
797        static LPCTSTR g_pszClassName;
798
799public:
800        //typedef CBlackListAwareComCreatorT<CComObjectCached<CSystemDeviceEnumeratorSpy>, CSystemDeviceEnumeratorSpy, &g_pszClassName> _ClassFactoryCreatorClass; // DECLARE_CLASSFACTORY override
801        typedef CComCreator2<CBlackListAwareComCreatorT<CComObject<CSystemDeviceEnumeratorSpy>, CSystemDeviceEnumeratorSpy, &g_pszClassName>, CBlackListAwareComCreatorT<CComAggObject<CSystemDeviceEnumeratorSpy>, CSystemDeviceEnumeratorSpy, &g_pszClassName> > _CreatorClass; // DECLARE_AGGREGATABLE override
802
803public:
804// CSystemDeviceEnumeratorSpy
805};
806
807__declspec(selectany) LPCTSTR CSystemDeviceEnumeratorSpy::g_pszClassName = _T("CSystemDeviceEnumeratorSpy");
808
809OBJECT_ENTRY_AUTO(__uuidof(SystemDeviceEnumeratorSpy), CSystemDeviceEnumeratorSpy)
Note: See TracBrowser for help on using the repository browser.