winsta: fix spec file
[reactos.git] / reactos / drivers / wdm / audio / backpln / portcls / filter_wavert.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/filter_wavert.c
5 * PURPOSE: portcls wave RT filter
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9 #include "private.h"
10
11 typedef struct
12 {
13 IPortFilterWaveRTVtbl *lpVtbl;
14
15 LONG ref;
16
17 IPortWaveRT* Port;
18 IPortPinWaveRT ** Pins;
19 SUBDEVICE_DESCRIPTOR * Descriptor;
20
21 }IPortFilterWaveRTImpl;
22
23 /*
24 * @implemented
25 */
26 NTSTATUS
27 NTAPI
28 IPortFilterWaveRT_fnQueryInterface(
29 IPortFilterWaveRT* iface,
30 IN REFIID refiid,
31 OUT PVOID* Output)
32 {
33 IPortFilterWaveRTImpl * This = (IPortFilterWaveRTImpl*)iface;
34
35 if (IsEqualGUIDAligned(refiid, &IID_IIrpTarget) ||
36 IsEqualGUIDAligned(refiid, &IID_IUnknown))
37 {
38 *Output = &This->lpVtbl;
39 InterlockedIncrement(&This->ref);
40 return STATUS_SUCCESS;
41 }
42 else if (IsEqualGUIDAligned(refiid, &IID_IPort))
43 {
44 *Output = This->Port;
45 This->Port->lpVtbl->AddRef(This->Port);
46 return STATUS_SUCCESS;
47 }
48
49
50 return STATUS_UNSUCCESSFUL;
51 }
52
53 /*
54 * @implemented
55 */
56 ULONG
57 NTAPI
58 IPortFilterWaveRT_fnAddRef(
59 IPortFilterWaveRT* iface)
60 {
61 IPortFilterWaveRTImpl * This = (IPortFilterWaveRTImpl*)iface;
62
63 return InterlockedIncrement(&This->ref);
64 }
65
66 /*
67 * @implemented
68 */
69 ULONG
70 NTAPI
71 IPortFilterWaveRT_fnRelease(
72 IPortFilterWaveRT* iface)
73 {
74 IPortFilterWaveRTImpl * This = (IPortFilterWaveRTImpl*)iface;
75
76 InterlockedDecrement(&This->ref);
77
78 if (This->ref == 0)
79 {
80 FreeItem(This, TAG_PORTCLASS);
81 return 0;
82 }
83 return This->ref;
84 }
85
86 /*
87 * @implemented
88 */
89 NTSTATUS
90 NTAPI
91 IPortFilterWaveRT_fnNewIrpTarget(
92 IN IPortFilterWaveRT* iface,
93 OUT struct IIrpTarget **OutTarget,
94 IN WCHAR * Name,
95 IN PUNKNOWN Unknown,
96 IN POOL_TYPE PoolType,
97 IN PDEVICE_OBJECT DeviceObject,
98 IN PIRP Irp,
99 IN KSOBJECT_CREATE *CreateObject)
100 {
101 NTSTATUS Status;
102 IPortPinWaveRT * Pin;
103 PKSPIN_CONNECT ConnectDetails;
104 IPortFilterWaveRTImpl * This = (IPortFilterWaveRTImpl *)iface;
105
106 ASSERT(This->Port);
107 ASSERT(This->Descriptor);
108 ASSERT(This->Pins);
109
110 DPRINT("IPortFilterWaveRT_fnNewIrpTarget entered\n");
111
112 /* let's verify the connection request */
113 Status = PcValidateConnectRequest(Irp, &This->Descriptor->Factory, &ConnectDetails);
114 if (!NT_SUCCESS(Status))
115 {
116 return STATUS_UNSUCCESSFUL;
117 }
118
119 if (This->Pins[ConnectDetails->PinId] && This->Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount)
120 {
121 /* release existing instance */
122 ASSERT(0);
123 This->Pins[ConnectDetails->PinId]->lpVtbl->Close(This->Pins[ConnectDetails->PinId], DeviceObject, NULL);
124 }
125
126 /* now create the pin */
127 Status = NewPortPinWaveRT(&Pin);
128 if (!NT_SUCCESS(Status))
129 {
130 return Status;
131 }
132
133 /* initialize the pin */
134 Status = Pin->lpVtbl->Init(Pin, This->Port, iface, ConnectDetails, &This->Descriptor->Factory.KsPinDescriptor[ConnectDetails->PinId], GetDeviceObjectFromPortWaveRT(This->Port));
135 if (!NT_SUCCESS(Status))
136 {
137 Pin->lpVtbl->Release(Pin);
138 return Status;
139 }
140
141 /* release existing pin */
142 if (This->Pins[ConnectDetails->PinId])
143 {
144 This->Pins[ConnectDetails->PinId]->lpVtbl->Release(This->Pins[ConnectDetails->PinId]);
145 }
146 /* store pin */
147 This->Pins[ConnectDetails->PinId] = Pin;
148
149 /* store result */
150 *OutTarget = (IIrpTarget*)Pin;
151
152 /* increment current instance count */
153 This->Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount++;
154
155 return Status;
156 }
157
158 /*
159 * @implemented
160 */
161 NTSTATUS
162 NTAPI
163 IPortFilterWaveRT_fnDeviceIoControl(
164 IN IPortFilterWaveRT* iface,
165 IN PDEVICE_OBJECT DeviceObject,
166 IN PIRP Irp)
167 {
168 PIO_STACK_LOCATION IoStack;
169 ISubdevice *SubDevice = NULL;
170 SUBDEVICE_DESCRIPTOR * Descriptor;
171 NTSTATUS Status;
172 IPortFilterWaveRTImpl * This = (IPortFilterWaveRTImpl *)iface;
173
174 IoStack = IoGetCurrentIrpStackLocation(Irp);
175 ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY);
176 Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&SubDevice);
177 ASSERT(Status == STATUS_SUCCESS);
178 ASSERT(SubDevice != NULL);
179
180 Status = SubDevice->lpVtbl->GetDescriptor(SubDevice, &Descriptor);
181 ASSERT(Status == STATUS_SUCCESS);
182 ASSERT(Descriptor != NULL);
183
184 SubDevice->lpVtbl->Release(SubDevice);
185
186 return PcPropertyHandler(Irp, Descriptor);
187 }
188
189 /*
190 * @implemented
191 */
192 NTSTATUS
193 NTAPI
194 IPortFilterWaveRT_fnRead(
195 IN IPortFilterWaveRT* iface,
196 IN PDEVICE_OBJECT DeviceObject,
197 IN PIRP Irp)
198 {
199 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
200 }
201
202 /*
203 * @implemented
204 */
205 NTSTATUS
206 NTAPI
207 IPortFilterWaveRT_fnWrite(
208 IN IPortFilterWaveRT* iface,
209 IN PDEVICE_OBJECT DeviceObject,
210 IN PIRP Irp)
211 {
212 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
213 }
214
215 /*
216 * @implemented
217 */
218 NTSTATUS
219 NTAPI
220 IPortFilterWaveRT_fnFlush(
221 IN IPortFilterWaveRT* iface,
222 IN PDEVICE_OBJECT DeviceObject,
223 IN PIRP Irp)
224 {
225 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
226 }
227
228 /*
229 * @implemented
230 */
231 NTSTATUS
232 NTAPI
233 IPortFilterWaveRT_fnClose(
234 IN IPortFilterWaveRT* iface,
235 IN PDEVICE_OBJECT DeviceObject,
236 IN PIRP Irp)
237 {
238 ULONG Index;
239 IPortFilterWaveRTImpl * This = (IPortFilterWaveRTImpl *)iface;
240
241 for(Index = 0; Index < This->Descriptor->Factory.PinDescriptorCount; Index++)
242 {
243 if (This->Pins[Index])
244 {
245 This->Pins[Index]->lpVtbl->Close(This->Pins[Index], DeviceObject, NULL);
246 }
247 }
248
249
250 Irp->IoStatus.Status = STATUS_SUCCESS;
251 Irp->IoStatus.Information = 0;
252 IoCompleteRequest(Irp, IO_NO_INCREMENT);
253
254 return STATUS_UNSUCCESSFUL;
255 }
256
257 /*
258 * @implemented
259 */
260 NTSTATUS
261 NTAPI
262 IPortFilterWaveRT_fnQuerySecurity(
263 IN IPortFilterWaveRT* iface,
264 IN PDEVICE_OBJECT DeviceObject,
265 IN PIRP Irp)
266 {
267 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
268 }
269
270 /*
271 * @implemented
272 */
273 NTSTATUS
274 NTAPI
275 IPortFilterWaveRT_fnSetSecurity(
276 IN IPortFilterWaveRT* iface,
277 IN PDEVICE_OBJECT DeviceObject,
278 IN PIRP Irp)
279 {
280 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
281 }
282
283 /*
284 * @implemented
285 */
286 BOOLEAN
287 NTAPI
288 IPortFilterWaveRT_fnFastDeviceIoControl(
289 IN IPortFilterWaveRT* iface,
290 IN PFILE_OBJECT FileObject,
291 IN BOOLEAN Wait,
292 IN PVOID InputBuffer,
293 IN ULONG InputBufferLength,
294 OUT PVOID OutputBuffer,
295 IN ULONG OutputBufferLength,
296 IN ULONG IoControlCode,
297 OUT PIO_STATUS_BLOCK StatusBlock,
298 IN PDEVICE_OBJECT DeviceObject)
299 {
300 ULONG Index;
301 PKSPROPERTY Property;
302 NTSTATUS Status;
303 ISubdevice * SubDevice = NULL;
304 PSUBDEVICE_DESCRIPTOR Descriptor = NULL;
305 IPortFilterWaveRTImpl * This = (IPortFilterWaveRTImpl *)iface;
306
307 Property = (PKSPROPERTY)InputBuffer;
308
309 if (InputBufferLength < sizeof(KSPROPERTY))
310 return FALSE;
311
312
313 /* get private interface */
314 Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&SubDevice);
315 if (!NT_SUCCESS(Status))
316 return FALSE;
317
318 /* get descriptor */
319 Status = SubDevice->lpVtbl->GetDescriptor(SubDevice, &Descriptor);
320 if (!NT_SUCCESS(Status))
321 {
322 SubDevice->lpVtbl->Release(SubDevice);
323 return FALSE;
324 }
325
326 for(Index = 0; Index < Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++)
327 {
328 if (IsEqualGUIDAligned(&Property->Set, Descriptor->FilterPropertySet.Properties[Index].Set))
329 {
330 FastPropertyHandler(FileObject, (PKSPROPERTY)InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, StatusBlock,
331 1,
332 &Descriptor->FilterPropertySet.Properties[Index],
333 Descriptor, SubDevice);
334 }
335 }
336 return TRUE;
337 }
338
339 /*
340 * @implemented
341 */
342 BOOLEAN
343 NTAPI
344 IPortFilterWaveRT_fnFastRead(
345 IN IPortFilterWaveRT* iface,
346 IN PFILE_OBJECT FileObject,
347 IN PLARGE_INTEGER FileOffset,
348 IN ULONG Length,
349 IN BOOLEAN Wait,
350 IN ULONG LockKey,
351 IN PVOID Buffer,
352 OUT PIO_STATUS_BLOCK StatusBlock,
353 IN PDEVICE_OBJECT DeviceObject)
354 {
355 UNIMPLEMENTED
356 return FALSE;
357 }
358
359 /*
360 * @implemented
361 */
362 BOOLEAN
363 NTAPI
364 IPortFilterWaveRT_fnFastWrite(
365 IN IPortFilterWaveRT* iface,
366 IN PFILE_OBJECT FileObject,
367 IN PLARGE_INTEGER FileOffset,
368 IN ULONG Length,
369 IN BOOLEAN Wait,
370 IN ULONG LockKey,
371 IN PVOID Buffer,
372 OUT PIO_STATUS_BLOCK StatusBlock,
373 IN PDEVICE_OBJECT DeviceObject)
374 {
375 UNIMPLEMENTED
376 return FALSE;
377 }
378
379 /*
380 * @implemented
381 */
382 static
383 NTSTATUS
384 NTAPI
385 IPortFilterWaveRT_fnInit(
386 IN IPortFilterWaveRT* iface,
387 IN IPortWaveRT* Port)
388 {
389 ISubdevice * ISubDevice;
390 SUBDEVICE_DESCRIPTOR * Descriptor;
391 NTSTATUS Status;
392 IPortFilterWaveRTImpl * This = (IPortFilterWaveRTImpl*)iface;
393
394 This->Port = Port;
395
396 /* get our private interface */
397 Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&ISubDevice);
398 if (!NT_SUCCESS(Status))
399 return STATUS_UNSUCCESSFUL;
400
401 /* get the subdevice descriptor */
402 Status = ISubDevice->lpVtbl->GetDescriptor(ISubDevice, &Descriptor);
403
404 /* release subdevice interface */
405 ISubDevice->lpVtbl->Release(ISubDevice);
406
407 if (!NT_SUCCESS(Status))
408 return STATUS_UNSUCCESSFUL;
409
410 /* save descriptor */
411 This->Descriptor = Descriptor;
412
413 /* allocate pin array */
414 This->Pins = AllocateItem(NonPagedPool, Descriptor->Factory.PinDescriptorCount * sizeof(IPortPinWaveRT*), TAG_PORTCLASS);
415
416 if (!This->Pins)
417 return STATUS_UNSUCCESSFUL;
418
419 /* increment reference count */
420 Port->lpVtbl->AddRef(Port);
421
422 return STATUS_SUCCESS;
423 }
424
425 static IPortFilterWaveRTVtbl vt_IPortFilterWaveRT =
426 {
427 IPortFilterWaveRT_fnQueryInterface,
428 IPortFilterWaveRT_fnAddRef,
429 IPortFilterWaveRT_fnRelease,
430 IPortFilterWaveRT_fnNewIrpTarget,
431 IPortFilterWaveRT_fnDeviceIoControl,
432 IPortFilterWaveRT_fnRead,
433 IPortFilterWaveRT_fnWrite,
434 IPortFilterWaveRT_fnFlush,
435 IPortFilterWaveRT_fnClose,
436 IPortFilterWaveRT_fnQuerySecurity,
437 IPortFilterWaveRT_fnSetSecurity,
438 IPortFilterWaveRT_fnFastDeviceIoControl,
439 IPortFilterWaveRT_fnFastRead,
440 IPortFilterWaveRT_fnFastWrite,
441 IPortFilterWaveRT_fnInit
442 };
443
444 NTSTATUS
445 NewPortFilterWaveRT(
446 OUT IPortFilterWaveRT ** OutFilter)
447 {
448 IPortFilterWaveRTImpl * This;
449
450 This = AllocateItem(NonPagedPool, sizeof(IPortFilterWaveRTImpl), TAG_PORTCLASS);
451 if (!This)
452 return STATUS_INSUFFICIENT_RESOURCES;
453
454 /* initialize IPortFilterWaveRT */
455 This->ref = 1;
456 This->lpVtbl = &vt_IPortFilterWaveRT;
457
458 /* return result */
459 *OutFilter = (IPortFilterWaveRT*)&This->lpVtbl;
460
461 return STATUS_SUCCESS;
462 }