[KSPROXY]
[reactos.git] / reactos / dll / directx / ksproxy / ksproxy.cpp
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy
4 * FILE: dll/directx/ksproxy/ksproxy.c
5 * PURPOSE: ActiveMovie Proxy functions
6 *
7 * PROGRAMMERS: Dmitry Chapyshev
8 Johannes Anderwald (janderwald@reactos.org)
9 */
10
11 #include "precomp.h"
12
13 const GUID KSPROPSETID_Pin = {0x8C134960, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
14 const GUID KSINTERFACESETID_Standard = {STATIC_KSINTERFACESETID_Standard};
15 const GUID CLSID_KsClockForwarder = {0x877e4351, 0x6fea, 0x11d0, {0xb8, 0x63, 0x00, 0xaa, 0x00, 0xa2, 0x16, 0xa1}};
16 const GUID CLSID_KsQualityForwarder = {0xe05592e4, 0xc0b5, 0x11d0, {0xa4, 0x39, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96}};
17 const GUID CLSID_KsIBasicAudioInterfaceHandler = {0xb9f8ac3e, 0x0f71, 0x11d2, {0xb7, 0x2c, 0x00, 0xc0, 0x4f, 0xb6, 0xbd, 0x3d}};
18 const GUID CLSID_Proxy = {0x17CCA71B, 0xECD7, 0x11D0, {0xB9, 0x08, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
19
20
21 static INTERFACE_TABLE InterfaceTable[] =
22 {
23 {&MEDIATYPE_Audio, CKsDataTypeHandler_Constructor},
24 {&KSINTERFACESETID_Standard, CKsInterfaceHandler_Constructor},
25 {&CLSID_KsClockForwarder, CKsClockForwarder_Constructor},
26 {&CLSID_KsQualityForwarder, CKsQualityForwarder_Constructor},
27 {&IID_IVPConfig, CVPConfig_Constructor},
28 {&IID_IVPVBIConfig, CVPVBIConfig_Constructor},
29 {&CLSID_KsIBasicAudioInterfaceHandler, CKsBasicAudio_Constructor},
30 {&CLSID_Proxy, CKsProxy_Constructor},
31 {NULL, NULL}
32 };
33
34 KSDDKAPI
35 HRESULT
36 WINAPI
37 KsSynchronousDeviceControl(
38 HANDLE Handle,
39 ULONG IoControl,
40 PVOID InBuffer,
41 ULONG InLength,
42 PVOID OutBuffer,
43 ULONG OutLength,
44 PULONG BytesReturned)
45 {
46 OVERLAPPED Overlapped;
47 DWORD Transferred;
48
49 /* zero overlapped */
50 RtlZeroMemory(&Overlapped, sizeof(OVERLAPPED));
51
52 /* create notification event */
53 Overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
54
55 if (!Overlapped.hEvent)
56 {
57 /* failed */
58 return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());
59 }
60
61 if (!DeviceIoControl(Handle, IoControl, InBuffer, InLength, OutBuffer, OutLength, BytesReturned, &Overlapped))
62 {
63 /* operation failed */
64 if (GetLastError() != ERROR_IO_PENDING)
65 {
66 /* failed */
67 CloseHandle(Overlapped.hEvent);
68 return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());
69 }
70 }
71
72 /* get result of pending operation */
73 if (!GetOverlappedResult(Handle, &Overlapped, &Transferred, TRUE))
74 {
75 /* failed */
76 CloseHandle(Overlapped.hEvent);
77 return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());
78 }
79
80 /* store number of bytes transferred */
81 *BytesReturned = Transferred;
82
83 /* close event object */
84 CloseHandle(Overlapped.hEvent);
85
86 /* done */
87 return NOERROR;
88 }
89
90 KSDDKAPI
91 HRESULT
92 WINAPI
93 KsResolveRequiredAttributes(
94 PKSDATARANGE DataRange,
95 KSMULTIPLE_ITEM *Attributes OPTIONAL)
96 {
97 //UNIMPLEMENTED
98 return NOERROR;
99 }
100
101 KSDDKAPI
102 HRESULT
103 WINAPI
104 KsOpenDefaultDevice(
105 REFGUID Category,
106 ACCESS_MASK Access,
107 PHANDLE DeviceHandle)
108 {
109 HDEVINFO hList;
110 SP_DEVINFO_DATA DeviceInfoData;
111 SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
112 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData;
113 WCHAR Path[MAX_PATH+sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W)];
114
115 /* open device list */
116 hList = SetupDiGetClassDevsW(&Category, NULL, NULL, DIGCF_DEVICEINTERFACE /* | DIGCF_PRESENT*/);
117
118 if (hList == INVALID_HANDLE_VALUE)
119 {
120 /* failed */
121 return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());
122 }
123
124 /* setup parameters */
125 DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
126 DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
127
128 if (SetupDiEnumDeviceInterfaces(hList, &DeviceInfoData, &Category, 0, &DeviceInterfaceData))
129 {
130 /* setup interface data struct */
131 DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)Path;
132 DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
133
134 /* get device interface details */
135 if (SetupDiGetDeviceInterfaceDetailW(hList, &DeviceInterfaceData, DeviceInterfaceDetailData, sizeof(Path), NULL, NULL))
136 {
137 /* open device */
138 *DeviceHandle = CreateFileW(DeviceInterfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL, NULL);
139
140 if (*DeviceHandle != INVALID_HANDLE_VALUE)
141 {
142 /* operation succeeded */
143 SetupDiDestroyDeviceInfoList(hList);
144 return NOERROR;
145 }
146 }
147 }
148
149 /* free device list */
150 SetupDiDestroyDeviceInfoList(hList);
151
152 /* failed */
153 return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());
154 }
155
156 KSDDKAPI
157 HRESULT
158 WINAPI
159 KsGetMultiplePinFactoryItems(
160 HANDLE FilterHandle,
161 ULONG PinFactoryId,
162 ULONG PropertyId,
163 PVOID *Items)
164 {
165 KSP_PIN Property;
166 ULONG BytesReturned, NumData;
167 HRESULT hResult;
168
169 /* zero pin property */
170 RtlZeroMemory(&Property, sizeof(KSP_PIN));
171 Property.Property.Set = KSPROPSETID_Pin;
172 Property.Property.Id = PropertyId;
173 Property.Property.Flags = KSPROPERTY_TYPE_GET;
174 Property.PinId = PinFactoryId;
175
176 /* query pin factory */
177 hResult = KsSynchronousDeviceControl(FilterHandle, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), NULL, 0, &BytesReturned);
178
179 if (hResult == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_INSUFFICIENT_BUFFER))
180 {
181 /* buffer too small */
182 hResult = KsSynchronousDeviceControl(FilterHandle, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), (PVOID)&NumData, sizeof(ULONG), &BytesReturned);
183
184 if (SUCCEEDED(hResult))
185 {
186 /* store required data size */
187 BytesReturned = NumData;
188 hResult = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_MORE_DATA);
189 }
190 }
191
192 if (hResult == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_MORE_DATA))
193 {
194 /* allocate data */
195 *Items = CoTaskMemAlloc(BytesReturned);
196
197 if (!*Items)
198 {
199 /* no memory */
200 return E_OUTOFMEMORY;
201 }
202
203 /* retry querying property */
204 hResult = KsSynchronousDeviceControl(FilterHandle, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), (PVOID)*Items, BytesReturned, &BytesReturned);
205
206 /* check for success */
207 if (FAILED(hResult))
208 {
209 /* free memory */
210 CoTaskMemFree(*Items);
211 }
212 }
213
214 /* done */
215 return hResult;
216 }
217
218 KSDDKAPI
219 HRESULT
220 WINAPI
221 KsGetMediaTypeCount(
222 HANDLE FilterHandle,
223 ULONG PinFactoryId,
224 ULONG *MediaTypeCount)
225 {
226 PKSMULTIPLE_ITEM MultipleItem;
227 HRESULT hr;
228
229 /* try get contrained data ranges */
230 hr = KsGetMultiplePinFactoryItems(FilterHandle, PinFactoryId, KSPROPERTY_PIN_CONSTRAINEDDATARANGES, (PVOID*)&MultipleItem);
231
232 /* check for failure*/
233 if (FAILED(hr))
234 {
235 /* try getting default data ranges */
236 hr = KsGetMultiplePinFactoryItems(FilterHandle, PinFactoryId, KSPROPERTY_PIN_DATARANGES, (PVOID*)&MultipleItem);
237 }
238
239 if (SUCCEEDED(hr))
240 {
241 /* store number of media types */
242 *MediaTypeCount = MultipleItem->Count;
243
244 /* free memory */
245 CoTaskMemFree(MultipleItem);
246 }
247
248 /* done */
249 return hr;
250 }
251
252 KSDDKAPI
253 HRESULT
254 WINAPI
255 KsGetMediaType(
256 int Position,
257 AM_MEDIA_TYPE *AmMediaType,
258 HANDLE FilterHandle,
259 ULONG PinFactoryId)
260 {
261 //UNIMPLEMENTED
262 return NOERROR;
263 }
264
265 extern "C"
266 KSDDKAPI
267 HRESULT
268 WINAPI
269 DllUnregisterServer(void)
270 {
271 return S_OK;
272 }
273
274 extern "C"
275 KSDDKAPI
276 HRESULT
277 WINAPI
278 DllRegisterServer(void)
279 {
280 return S_OK;
281 }
282
283 KSDDKAPI
284 HRESULT
285 WINAPI
286 DllGetClassObject(
287 REFCLSID rclsid,
288 REFIID riid,
289 LPVOID *ppv)
290 {
291 UINT i;
292 HRESULT hres = E_OUTOFMEMORY;
293 IClassFactory * pcf = NULL;
294
295 if (!ppv)
296 return E_INVALIDARG;
297
298 *ppv = NULL;
299
300 for (i = 0; InterfaceTable[i].riid; i++)
301 {
302 if (IsEqualIID(InterfaceTable[i].riid, rclsid))
303 {
304 pcf = CClassFactory_fnConstructor(InterfaceTable[i].lpfnCI, NULL, NULL);
305 break;
306 }
307 }
308
309 if (!pcf)
310 {
311 return CLASS_E_CLASSNOTAVAILABLE;
312 }
313
314 hres = pcf->QueryInterface(riid, ppv);
315 pcf->Release();
316
317 return hres;
318 }
319
320 KSDDKAPI
321 HRESULT
322 WINAPI
323 DllCanUnloadNow(void)
324 {
325 return S_OK;
326 }
327