sync with trunk r46493
[reactos.git] / dll / directx / ksproxy / enum_mediatypes.cpp
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Network Provider for MPEG2 based networks
4 * FILE: dll/directx/msdvbnp/enum_mediatypes.cpp
5 * PURPOSE: IEnumMediaTypes interface
6 *
7 * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
8 */
9 #include "precomp.h"
10
11 class CEnumMediaTypes : public IEnumMediaTypes
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 HRESULT STDMETHODCALLTYPE Next(ULONG cMediaTypes, AM_MEDIA_TYPE **ppMediaTypes, ULONG *pcFetched);
33 HRESULT STDMETHODCALLTYPE Skip(ULONG cMediaTypes);
34 HRESULT STDMETHODCALLTYPE Reset();
35 HRESULT STDMETHODCALLTYPE Clone(IEnumMediaTypes **ppEnum);
36
37
38 CEnumMediaTypes(ULONG MediaTypeCount, AM_MEDIA_TYPE * MediaTypes) : m_Ref(0), m_MediaTypeCount(MediaTypeCount), m_MediaTypes(MediaTypes), m_Index(0){};
39 virtual ~CEnumMediaTypes(){};
40
41 protected:
42 LONG m_Ref;
43 ULONG m_MediaTypeCount;
44 AM_MEDIA_TYPE * m_MediaTypes;
45 ULONG m_Index;
46 };
47
48 HRESULT
49 STDMETHODCALLTYPE
50 CEnumMediaTypes::QueryInterface(
51 IN REFIID refiid,
52 OUT PVOID* Output)
53 {
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_IEnumMediaTypes))
61 {
62 *Output = (IEnumMediaTypes*)(this);
63 reinterpret_cast<IEnumMediaTypes*>(*Output)->AddRef();
64 return NOERROR;
65 }
66
67 return E_NOINTERFACE;
68 }
69
70 //-------------------------------------------------------------------
71 // IEnumMediaTypes
72 //
73
74 HRESULT
75 STDMETHODCALLTYPE
76 CEnumMediaTypes::Next(
77 ULONG cMediaTypes,
78 AM_MEDIA_TYPE **ppMediaTypes,
79 ULONG *pcFetched)
80 {
81 ULONG i = 0;
82 AM_MEDIA_TYPE * MediaType;
83
84 if (!ppMediaTypes)
85 return E_POINTER;
86
87 if (cMediaTypes > 1 && !pcFetched)
88 return E_INVALIDARG;
89
90 while(i < cMediaTypes)
91 {
92 if (m_Index + i >= m_MediaTypeCount)
93 break;
94
95 MediaType = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
96 if (!MediaType)
97 break;
98
99 if (m_MediaTypes[m_Index + i].cbFormat)
100 {
101 LPBYTE pFormat = (LPBYTE)CoTaskMemAlloc(m_MediaTypes[m_Index + i].cbFormat);
102 if (!pFormat)
103 {
104 CoTaskMemFree(MediaType);
105 break;
106 }
107
108 CopyMemory(MediaType, &m_MediaTypes[m_Index + i], sizeof(AM_MEDIA_TYPE));
109 MediaType->pbFormat = pFormat;
110 CopyMemory(MediaType->pbFormat, m_MediaTypes[m_Index + i].pbFormat, m_MediaTypes[m_Index + i].cbFormat);
111 MediaType->pUnk = (IUnknown *)this;
112 MediaType->pUnk->AddRef();
113 }
114 else
115 {
116 CopyMemory(MediaType, &m_MediaTypes[m_Index + i], sizeof(AM_MEDIA_TYPE));
117 }
118
119 if (MediaType->pUnk)
120 {
121 MediaType->pUnk->AddRef();
122 }
123
124 ppMediaTypes[i] = MediaType;
125 i++;
126 }
127
128 if (pcFetched)
129 {
130 *pcFetched = i;
131 }
132
133 m_Index += i;
134 if (i < cMediaTypes)
135 return S_FALSE;
136 else
137 return S_OK;
138 }
139
140 HRESULT
141 STDMETHODCALLTYPE
142 CEnumMediaTypes::Skip(
143 ULONG cMediaTypes)
144 {
145 if (cMediaTypes + m_Index >= m_MediaTypeCount)
146 {
147 return S_FALSE;
148 }
149
150 m_Index += cMediaTypes;
151 return S_OK;
152 }
153
154 HRESULT
155 STDMETHODCALLTYPE
156 CEnumMediaTypes::Reset()
157 {
158 m_Index = 0;
159 return S_OK;
160 }
161
162 HRESULT
163 STDMETHODCALLTYPE
164 CEnumMediaTypes::Clone(
165 IEnumMediaTypes **ppEnum)
166 {
167 #ifdef KSPROXY_TRACE
168 OutputDebugStringW(L"CEnumMediaTypes::Clone : NotImplemented\n");
169 #endif
170 return E_NOTIMPL;
171 }
172
173 HRESULT
174 WINAPI
175 CEnumMediaTypes_fnConstructor(
176 ULONG MediaTypeCount,
177 AM_MEDIA_TYPE * MediaTypes,
178 REFIID riid,
179 LPVOID * ppv)
180 {
181 CEnumMediaTypes * handler = new CEnumMediaTypes(MediaTypeCount, MediaTypes);
182
183 #ifdef KSPROXY_TRACE
184 WCHAR Buffer[MAX_PATH];
185 LPOLESTR lpstr;
186 StringFromCLSID(riid, &lpstr);
187 swprintf(Buffer, L"CEnumMediaTypes_fnConstructor riid %s\n", lpstr);
188 OutputDebugStringW(Buffer);
189 #endif
190
191 if (!handler)
192 {
193 CoTaskMemFree(MediaTypes);
194 return E_OUTOFMEMORY;
195 }
196
197 if (FAILED(handler->QueryInterface(riid, ppv)))
198 {
199 /* not supported */
200 delete handler;
201 return E_NOINTERFACE;
202 }
203
204 return NOERROR;
205 }
206