462ffda24fc15c536ee504496142d79812b802cf
[reactos.git] / reactos / 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 WCHAR Buffer[MAX_PATH];
68 LPOLESTR lpstr;
69 StringFromCLSID(refiid, &lpstr);
70 swprintf(Buffer, L"CEnumMediaTypes::QueryInterface: NoInterface for %s\n", lpstr);
71 OutputDebugStringW(Buffer);
72 CoTaskMemFree(lpstr);
73
74 return E_NOINTERFACE;
75 }
76
77 //-------------------------------------------------------------------
78 // IEnumMediaTypes
79 //
80
81 HRESULT
82 STDMETHODCALLTYPE
83 CEnumMediaTypes::Next(
84 ULONG cMediaTypes,
85 AM_MEDIA_TYPE **ppMediaTypes,
86 ULONG *pcFetched)
87 {
88 ULONG i = 0;
89 AM_MEDIA_TYPE * MediaType;
90
91 if (!ppMediaTypes)
92 return E_POINTER;
93
94 if (cMediaTypes > 1 && !pcFetched)
95 return E_INVALIDARG;
96
97 while(i < cMediaTypes)
98 {
99 if (m_Index + i >= m_MediaTypeCount)
100 break;
101
102 MediaType = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
103 if (!MediaType)
104 break;
105
106 if (m_MediaTypes[m_Index + i].cbFormat)
107 {
108 LPBYTE pFormat = (LPBYTE)CoTaskMemAlloc(m_MediaTypes[m_Index + i].cbFormat);
109 if (!pFormat)
110 {
111 CoTaskMemFree(MediaType);
112 break;
113 }
114
115 CopyMemory(MediaType, &m_MediaTypes[m_Index + i], sizeof(AM_MEDIA_TYPE));
116 MediaType->pbFormat = pFormat;
117 CopyMemory(MediaType->pbFormat, m_MediaTypes[m_Index + i].pbFormat, m_MediaTypes[m_Index + i].cbFormat);
118 MediaType->pUnk = (IUnknown *)this;
119 MediaType->pUnk->AddRef();
120 }
121 else
122 {
123 CopyMemory(MediaType, &m_MediaTypes[m_Index + i], sizeof(AM_MEDIA_TYPE));
124 }
125
126 if (MediaType->pUnk)
127 {
128 MediaType->pUnk->AddRef();
129 }
130
131 ppMediaTypes[i] = MediaType;
132 i++;
133 }
134
135 if (pcFetched)
136 {
137 *pcFetched = i;
138 }
139
140 m_Index += i;
141 if (i < cMediaTypes)
142 return S_FALSE;
143 else
144 return S_OK;
145 }
146
147 HRESULT
148 STDMETHODCALLTYPE
149 CEnumMediaTypes::Skip(
150 ULONG cMediaTypes)
151 {
152 if (cMediaTypes + m_Index >= m_MediaTypeCount)
153 {
154 return S_FALSE;
155 }
156
157 m_Index += cMediaTypes;
158 return S_OK;
159 }
160
161 HRESULT
162 STDMETHODCALLTYPE
163 CEnumMediaTypes::Reset()
164 {
165 m_Index = 0;
166 return S_OK;
167 }
168
169 HRESULT
170 STDMETHODCALLTYPE
171 CEnumMediaTypes::Clone(
172 IEnumMediaTypes **ppEnum)
173 {
174 OutputDebugStringW(L"CEnumMediaTypes::Clone : NotImplemented\n");
175 return E_NOTIMPL;
176 }
177
178 HRESULT
179 WINAPI
180 CEnumMediaTypes_fnConstructor(
181 ULONG MediaTypeCount,
182 AM_MEDIA_TYPE * MediaTypes,
183 REFIID riid,
184 LPVOID * ppv)
185 {
186 CEnumMediaTypes * handler = new CEnumMediaTypes(MediaTypeCount, MediaTypes);
187
188 #ifdef KSPROXY_TRACE
189 WCHAR Buffer[MAX_PATH];
190 LPOLESTR lpstr;
191 StringFromCLSID(riid, &lpstr);
192 swprintf(Buffer, L"CEnumMediaTypes_fnConstructor riid %s pUnknown %p\n", lpstr, pUnknown);
193 OutputDebugStringW(Buffer);
194 #endif
195
196 if (!handler)
197 {
198 CoTaskMemFree(MediaTypes);
199 return E_OUTOFMEMORY;
200 }
201
202 if (FAILED(handler->QueryInterface(riid, ppv)))
203 {
204 /* not supported */
205 delete handler;
206 return E_NOINTERFACE;
207 }
208
209 return NOERROR;
210 }
211