xref: /reactos/dll/directx/ksproxy/enumpins.cpp (revision 50cf16b3)
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 }