winsta: fix spec file
[reactos.git] / reactos / drivers / wdm / audio / backpln / portcls / filter_topology.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/filter_topology.c
5 * PURPOSE: portcls topology filter
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9 #include "private.h"
10
11 typedef struct
12 {
13 IPortFilterTopologyVtbl *lpVtbl;
14
15 LONG ref;
16
17 IPortTopology* Port;
18 SUBDEVICE_DESCRIPTOR * Descriptor;
19 ISubdevice *SubDevice;
20
21 }IPortFilterTopologyImpl;
22
23 /*
24 * @implemented
25 */
26 NTSTATUS
27 NTAPI
28 IPortFilterTopology_fnQueryInterface(
29 IPortFilterTopology* iface,
30 IN REFIID refiid,
31 OUT PVOID* Output)
32 {
33 IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)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 return STATUS_UNSUCCESSFUL;
50 }
51
52 /*
53 * @implemented
54 */
55 ULONG
56 NTAPI
57 IPortFilterTopology_fnAddRef(
58 IPortFilterTopology* iface)
59 {
60 IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface;
61
62 return InterlockedIncrement(&This->ref);
63 }
64
65 /*
66 * @implemented
67 */
68 ULONG
69 NTAPI
70 IPortFilterTopology_fnRelease(
71 IPortFilterTopology* iface)
72 {
73 IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface;
74
75 InterlockedDecrement(&This->ref);
76
77 if (This->ref == 0)
78 {
79 FreeItem(This, TAG_PORTCLASS);
80 return 0;
81 }
82 return This->ref;
83 }
84
85 /*
86 * @implemented
87 */
88 NTSTATUS
89 NTAPI
90 IPortFilterTopology_fnNewIrpTarget(
91 IN IPortFilterTopology* iface,
92 OUT struct IIrpTarget **OutTarget,
93 IN WCHAR * Name,
94 IN PUNKNOWN Unknown,
95 IN POOL_TYPE PoolType,
96 IN PDEVICE_OBJECT DeviceObject,
97 IN PIRP Irp,
98 IN KSOBJECT_CREATE *CreateObject)
99 {
100 DPRINT("IPortFilterTopology_fnNewIrpTarget entered\n");
101
102 return STATUS_NOT_SUPPORTED;
103 }
104
105 /*
106 * @implemented
107 */
108 NTSTATUS
109 NTAPI
110 IPortFilterTopology_fnDeviceIoControl(
111 IN IPortFilterTopology* iface,
112 IN PDEVICE_OBJECT DeviceObject,
113 IN PIRP Irp)
114 {
115 PIO_STACK_LOCATION IoStack;
116 IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl *)iface;
117
118 IoStack = IoGetCurrentIrpStackLocation(Irp);
119 ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY);
120
121 return PcPropertyHandler(Irp, This->Descriptor);
122 }
123
124 /*
125 * @implemented
126 */
127 NTSTATUS
128 NTAPI
129 IPortFilterTopology_fnRead(
130 IN IPortFilterTopology* iface,
131 IN PDEVICE_OBJECT DeviceObject,
132 IN PIRP Irp)
133 {
134 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
135 }
136
137 /*
138 * @implemented
139 */
140 NTSTATUS
141 NTAPI
142 IPortFilterTopology_fnWrite(
143 IN IPortFilterTopology* iface,
144 IN PDEVICE_OBJECT DeviceObject,
145 IN PIRP Irp)
146 {
147 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
148 }
149
150 /*
151 * @implemented
152 */
153 NTSTATUS
154 NTAPI
155 IPortFilterTopology_fnFlush(
156 IN IPortFilterTopology* iface,
157 IN PDEVICE_OBJECT DeviceObject,
158 IN PIRP Irp)
159 {
160 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
161 }
162
163 /*
164 * @implemented
165 */
166 NTSTATUS
167 NTAPI
168 IPortFilterTopology_fnClose(
169 IN IPortFilterTopology* iface,
170 IN PDEVICE_OBJECT DeviceObject,
171 IN PIRP Irp)
172 {
173 NTSTATUS Status = STATUS_SUCCESS;
174 IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl *)iface;
175
176 /* FIXME handle DirectSound */
177
178 if (This->ref == 1)
179 {
180 /* release reference to port */
181 This->SubDevice->lpVtbl->Release(This->SubDevice);
182
183 /* time to shutdown the audio system */
184 Status = This->SubDevice->lpVtbl->ReleaseChildren(This->SubDevice);
185 }
186
187 Irp->IoStatus.Status = Status;
188 Irp->IoStatus.Information = 0;
189 IoCompleteRequest(Irp, IO_NO_INCREMENT);
190
191 return STATUS_SUCCESS;
192 }
193
194 /*
195 * @implemented
196 */
197 NTSTATUS
198 NTAPI
199 IPortFilterTopology_fnQuerySecurity(
200 IN IPortFilterTopology* iface,
201 IN PDEVICE_OBJECT DeviceObject,
202 IN PIRP Irp)
203 {
204 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
205 }
206
207 /*
208 * @implemented
209 */
210 NTSTATUS
211 NTAPI
212 IPortFilterTopology_fnSetSecurity(
213 IN IPortFilterTopology* iface,
214 IN PDEVICE_OBJECT DeviceObject,
215 IN PIRP Irp)
216 {
217 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
218 }
219
220 /*
221 * @implemented
222 */
223 BOOLEAN
224 NTAPI
225 IPortFilterTopology_fnFastDeviceIoControl(
226 IN IPortFilterTopology* iface,
227 IN PFILE_OBJECT FileObject,
228 IN BOOLEAN Wait,
229 IN PVOID InputBuffer,
230 IN ULONG InputBufferLength,
231 OUT PVOID OutputBuffer,
232 IN ULONG OutputBufferLength,
233 IN ULONG IoControlCode,
234 OUT PIO_STATUS_BLOCK StatusBlock,
235 IN PDEVICE_OBJECT DeviceObject)
236 {
237 ULONG Index;
238 PKSPROPERTY Property;
239 IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface;
240
241 Property = (PKSPROPERTY)InputBuffer;
242
243 if (InputBufferLength < sizeof(KSPROPERTY))
244 return FALSE;
245
246 for(Index = 0; Index < This->Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++)
247 {
248 if (IsEqualGUIDAligned(&Property->Set, This->Descriptor->FilterPropertySet.Properties[Index].Set))
249 {
250 FastPropertyHandler(FileObject, (PKSPROPERTY)InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, StatusBlock,
251 1,
252 &This->Descriptor->FilterPropertySet.Properties[Index],
253 This->Descriptor, This->SubDevice);
254 }
255 }
256 return TRUE;
257 }
258
259 /*
260 * @implemented
261 */
262 BOOLEAN
263 NTAPI
264 IPortFilterTopology_fnFastRead(
265 IN IPortFilterTopology* iface,
266 IN PFILE_OBJECT FileObject,
267 IN PLARGE_INTEGER FileOffset,
268 IN ULONG Length,
269 IN BOOLEAN Wait,
270 IN ULONG LockKey,
271 IN PVOID Buffer,
272 OUT PIO_STATUS_BLOCK StatusBlock,
273 IN PDEVICE_OBJECT DeviceObject)
274 {
275 return FALSE;
276 }
277
278 /*
279 * @implemented
280 */
281 BOOLEAN
282 NTAPI
283 IPortFilterTopology_fnFastWrite(
284 IN IPortFilterTopology* iface,
285 IN PFILE_OBJECT FileObject,
286 IN PLARGE_INTEGER FileOffset,
287 IN ULONG Length,
288 IN BOOLEAN Wait,
289 IN ULONG LockKey,
290 IN PVOID Buffer,
291 OUT PIO_STATUS_BLOCK StatusBlock,
292 IN PDEVICE_OBJECT DeviceObject)
293 {
294 return FALSE;
295 }
296
297 /*
298 * @implemented
299 */
300 static
301 NTSTATUS
302 NTAPI
303 IPortFilterTopology_fnInit(
304 IN IPortFilterTopology* iface,
305 IN IPortTopology* Port)
306 {
307 ISubdevice * ISubDevice;
308 SUBDEVICE_DESCRIPTOR * Descriptor;
309 NTSTATUS Status;
310 IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface;
311
312 /* get our private interface */
313 Status = Port->lpVtbl->QueryInterface(Port, &IID_ISubdevice, (PVOID*)&ISubDevice);
314 if (!NT_SUCCESS(Status))
315 return STATUS_UNSUCCESSFUL;
316
317 /* get the subdevice descriptor */
318 Status = ISubDevice->lpVtbl->GetDescriptor(ISubDevice, &Descriptor);
319
320 /* store subdevice interface */
321 This->SubDevice = ISubDevice;
322
323 if (!NT_SUCCESS(Status))
324 return STATUS_UNSUCCESSFUL;
325
326 /* save descriptor */
327 This->Descriptor = Descriptor;
328
329 /* store port object */
330 This->Port = Port;
331
332 return STATUS_SUCCESS;
333 }
334
335 static IPortFilterTopologyVtbl vt_IPortFilterTopology =
336 {
337 IPortFilterTopology_fnQueryInterface,
338 IPortFilterTopology_fnAddRef,
339 IPortFilterTopology_fnRelease,
340 IPortFilterTopology_fnNewIrpTarget,
341 IPortFilterTopology_fnDeviceIoControl,
342 IPortFilterTopology_fnRead,
343 IPortFilterTopology_fnWrite,
344 IPortFilterTopology_fnFlush,
345 IPortFilterTopology_fnClose,
346 IPortFilterTopology_fnQuerySecurity,
347 IPortFilterTopology_fnSetSecurity,
348 IPortFilterTopology_fnFastDeviceIoControl,
349 IPortFilterTopology_fnFastRead,
350 IPortFilterTopology_fnFastWrite,
351 IPortFilterTopology_fnInit
352 };
353
354 NTSTATUS
355 NewPortFilterTopology(
356 OUT IPortFilterTopology ** OutFilter)
357 {
358 IPortFilterTopologyImpl * This;
359
360 This = AllocateItem(NonPagedPool, sizeof(IPortFilterTopologyImpl), TAG_PORTCLASS);
361 if (!This)
362 return STATUS_INSUFFICIENT_RESOURCES;
363
364 /* initialize IPortFilterTopology */
365 This->ref = 1;
366 This->lpVtbl = &vt_IPortFilterTopology;
367
368 /* return result */
369 *OutFilter = (IPortFilterTopology*)&This->lpVtbl;
370
371 return STATUS_SUCCESS;
372 }