1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Network Provider for MPEG2 based networks 4 * FILE: dll/directx/ksproxy/enumpins.cpp 5 * PURPOSE: IEnumPins interface 6 * 7 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org) 8 */ 9 #include "precomp.h" 10 11 class CEnumPins : public IEnumPins 12 { 13 public: 14 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); 15 16 STDMETHODIMP_(ULONG) AddRef() 17 { 18 InterlockedIncrement(&m_Ref); 19 return m_Ref; 20 } 21 STDMETHODIMP_(ULONG) Release() 22 { 23 InterlockedDecrement(&m_Ref); 24 if (!m_Ref) 25 { 26 delete this; 27 return 0; 28 } 29 return m_Ref; 30 } 31 32 33 HRESULT STDMETHODCALLTYPE Next(ULONG cPins, IPin **ppPins, ULONG *pcFetched); 34 HRESULT STDMETHODCALLTYPE Skip(ULONG cPins); 35 HRESULT STDMETHODCALLTYPE Reset(); 36 HRESULT STDMETHODCALLTYPE Clone(IEnumPins **ppEnum); 37 38 CEnumPins(std::vector<IPin*> Pins) : m_Ref(0), m_Pins(Pins), m_Index(0){}; 39 virtual ~CEnumPins(){}; 40 41 protected: 42 LONG m_Ref; 43 std::vector<IPin*> m_Pins; 44 ULONG m_Index; 45 }; 46 47 HRESULT 48 STDMETHODCALLTYPE 49 CEnumPins::QueryInterface( 50 IN REFIID refiid, 51 OUT PVOID* Output) 52 { 53 *Output = NULL; 54 if (IsEqualGUID(refiid, IID_IUnknown)) 55 { 56 *Output = PVOID(this); 57 reinterpret_cast<IUnknown*>(*Output)->AddRef(); 58 return NOERROR; 59 } 60 if (IsEqualGUID(refiid, IID_IEnumPins)) 61 { 62 *Output = (IEnumPins*)(this); 63 reinterpret_cast<IEnumPins*>(*Output)->AddRef(); 64 return NOERROR; 65 } 66 67 WCHAR Buffer[100]; 68 LPOLESTR lpstr; 69 StringFromCLSID(refiid, &lpstr); 70 swprintf(Buffer, L"CEnumPins::QueryInterface: NoInterface for %s\n", lpstr); 71 OutputDebugStringW(Buffer); 72 CoTaskMemFree(lpstr); 73 74 return E_NOINTERFACE; 75 } 76 77 HRESULT 78 STDMETHODCALLTYPE 79 CEnumPins::Next( 80 ULONG cPins, 81 IPin **ppPins, 82 ULONG *pcFetched) 83 { 84 ULONG i = 0; 85 86 if (!ppPins) 87 return E_POINTER; 88 89 if (cPins > 1 && !pcFetched) 90 return E_INVALIDARG; 91 92 while(i < cPins) 93 { 94 if (m_Index + i >= m_Pins.size()) 95 break; 96 97 ppPins[i] = m_Pins[m_Index + i]; 98 m_Pins[m_Index + i]->AddRef(); 99 100 i++; 101 } 102 103 if (pcFetched) 104 { 105 *pcFetched = i; 106 } 107 108 m_Index += i; 109 if (i < cPins) 110 return S_FALSE; 111 else 112 return S_OK; 113 } 114 115 HRESULT 116 STDMETHODCALLTYPE 117 CEnumPins::Skip( 118 ULONG cPins) 119 { 120 if (cPins + m_Index >= m_Pins.size()) 121 { 122 return S_FALSE; 123 } 124 125 m_Index += cPins; 126 return S_OK; 127 } 128 129 HRESULT 130 STDMETHODCALLTYPE 131 CEnumPins::Reset() 132 { 133 m_Index = 0; 134 return S_OK; 135 } 136 137 HRESULT 138 STDMETHODCALLTYPE 139 CEnumPins::Clone( 140 IEnumPins **ppEnum) 141 { 142 #ifdef KSPROXY_TRACE 143 OutputDebugStringW(L"CEnumPins::Clone : NotImplemented\n"); 144 #endif 145 146 return E_NOTIMPL; 147 } 148 149 HRESULT 150 WINAPI 151 CEnumPins_fnConstructor( 152 std::vector<IPin*> Pins, 153 REFIID riid, 154 LPVOID * ppv) 155 { 156 CEnumPins * handler = new CEnumPins(Pins); 157 158 if (!handler) 159 return E_OUTOFMEMORY; 160 161 if (FAILED(handler->QueryInterface(riid, ppv))) 162 { 163 /* not supported */ 164 delete handler; 165 return E_NOINTERFACE; 166 } 167 168 return NOERROR; 169 }