1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/filter_wavepci.cpp
5 * PURPOSE: portcls wave pci filter
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9 #include "private.hpp"
10
11 #define NDEBUG
12 #include <debug.h>
13
14 class CPortFilterWavePci : public CUnknownImpl<IPortFilterWavePci>
15 {
16 public:
17 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
18
19 IMP_IPortFilterPci;
CPortFilterWavePci(IUnknown * OuterUnknown)20 CPortFilterWavePci(IUnknown *OuterUnknown){}
~CPortFilterWavePci()21 virtual ~CPortFilterWavePci(){}
22
23 protected:
24 IPortWavePci* m_Port;
25 IPortPinWavePci ** m_Pins;
26 SUBDEVICE_DESCRIPTOR * m_Descriptor;
27 };
28
29 NTSTATUS
30 NTAPI
QueryInterface(IN REFIID refiid,OUT PVOID * Output)31 CPortFilterWavePci::QueryInterface(
32
33 IN REFIID refiid,
34 OUT PVOID* Output)
35 {
36
37 if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) ||
38 IsEqualGUIDAligned(refiid, IID_IUnknown))
39 {
40 *Output = PVOID(PUNKNOWN(this));
41 PUNKNOWN(*Output)->AddRef();
42 return STATUS_SUCCESS;
43 }
44 else if (IsEqualGUIDAligned(refiid, IID_IPort))
45 {
46 *Output = PUNKNOWN(m_Port);
47 PUNKNOWN(*Output)->AddRef();
48 return STATUS_SUCCESS;
49 }
50
51 return STATUS_UNSUCCESSFUL;
52 }
53
54 NTSTATUS
55 NTAPI
NewIrpTarget(OUT struct IIrpTarget ** OutTarget,IN PCWSTR Name,IN PUNKNOWN Unknown,IN POOL_TYPE PoolType,IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN KSOBJECT_CREATE * CreateObject)56 CPortFilterWavePci::NewIrpTarget(
57 OUT struct IIrpTarget **OutTarget,
58 IN PCWSTR Name,
59 IN PUNKNOWN Unknown,
60 IN POOL_TYPE PoolType,
61 IN PDEVICE_OBJECT DeviceObject,
62 IN PIRP Irp,
63 IN KSOBJECT_CREATE *CreateObject)
64 {
65 NTSTATUS Status;
66 IPortPinWavePci * Pin;
67 PKSPIN_CONNECT ConnectDetails;
68
69 #if 0
70 ASSERT(m_Port);
71 ASSERT(m_Descriptor);
72 ASSERT(m_Pins);
73 #endif
74
75 DPRINT("CPortFilterWavePci::NewIrpTarget entered\n");
76
77 // let's verify the connection request
78 Status = PcValidateConnectRequest(Irp, &m_Descriptor->Factory, &ConnectDetails);
79 if (!NT_SUCCESS(Status))
80 {
81 return STATUS_UNSUCCESSFUL;
82 }
83
84 if (m_Pins[ConnectDetails->PinId] &&
85 (m_Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount == m_Descriptor->Factory.Instances[ConnectDetails->PinId].MaxFilterInstanceCount))
86 {
87 // no available instance
88 return STATUS_UNSUCCESSFUL;
89 }
90
91 // now create the pin
92 Status = NewPortPinWavePci(&Pin);
93 if (!NT_SUCCESS(Status))
94 {
95 return Status;
96 }
97
98 // initialize the pin
99 Status = Pin->Init(m_Port, this, ConnectDetails, &m_Descriptor->Factory.KsPinDescriptor[ConnectDetails->PinId], GetDeviceObjectFromPortWavePci(m_Port));
100 if (!NT_SUCCESS(Status))
101 {
102 Pin->Release();
103 return Status;
104 }
105
106 // store pin
107 m_Pins[ConnectDetails->PinId] = Pin;
108
109 // store result
110 *OutTarget = (IIrpTarget*)Pin;
111
112 // increment current instance count
113 m_Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount++;
114
115 return Status;
116 }
117
118 NTSTATUS
119 NTAPI
DeviceIoControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)120 CPortFilterWavePci::DeviceIoControl(
121 IN PDEVICE_OBJECT DeviceObject,
122 IN PIRP Irp)
123 {
124 PIO_STACK_LOCATION IoStack;
125 NTSTATUS Status;
126
127 IoStack = IoGetCurrentIrpStackLocation(Irp);
128
129 if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY)
130 {
131 DPRINT("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength);
132
133 Irp->IoStatus.Status = STATUS_SUCCESS;
134
135 IoCompleteRequest(Irp, IO_NO_INCREMENT);
136 return STATUS_SUCCESS;
137 }
138
139 Status = PcHandlePropertyWithTable(Irp, m_Descriptor->FilterPropertySetCount, m_Descriptor->FilterPropertySet, m_Descriptor);
140 if (Status != STATUS_PENDING)
141 {
142 Irp->IoStatus.Status = Status;
143 DPRINT("Result %x Length %u\n", Status, Irp->IoStatus.Information);
144 IoCompleteRequest(Irp, IO_NO_INCREMENT);
145 }
146 return Status;
147 }
148
149 NTSTATUS
150 NTAPI
Read(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)151 CPortFilterWavePci::Read(
152 IN PDEVICE_OBJECT DeviceObject,
153 IN PIRP Irp)
154 {
155 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
156 }
157
158 NTSTATUS
159 NTAPI
Write(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)160 CPortFilterWavePci::Write(
161 IN PDEVICE_OBJECT DeviceObject,
162 IN PIRP Irp)
163 {
164 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
165 }
166
167 NTSTATUS
168 NTAPI
Flush(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)169 CPortFilterWavePci::Flush(
170 IN PDEVICE_OBJECT DeviceObject,
171 IN PIRP Irp)
172 {
173 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
174 }
175
176 NTSTATUS
177 NTAPI
Close(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)178 CPortFilterWavePci::Close(
179 IN PDEVICE_OBJECT DeviceObject,
180 IN PIRP Irp)
181 {
182 Irp->IoStatus.Status = STATUS_SUCCESS;
183 Irp->IoStatus.Information = 0;
184 IoCompleteRequest(Irp, IO_NO_INCREMENT);
185
186 return STATUS_UNSUCCESSFUL;
187 }
188
189 NTSTATUS
190 NTAPI
QuerySecurity(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)191 CPortFilterWavePci::QuerySecurity(
192 IN PDEVICE_OBJECT DeviceObject,
193 IN PIRP Irp)
194 {
195 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
196 }
197
198 NTSTATUS
199 NTAPI
SetSecurity(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)200 CPortFilterWavePci::SetSecurity(
201 IN PDEVICE_OBJECT DeviceObject,
202 IN PIRP Irp)
203 {
204 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
205 }
206
207 BOOLEAN
208 NTAPI
FastDeviceIoControl(IN PFILE_OBJECT FileObject,IN BOOLEAN Wait,IN PVOID InputBuffer,IN ULONG InputBufferLength,OUT PVOID OutputBuffer,IN ULONG OutputBufferLength,IN ULONG IoControlCode,OUT PIO_STATUS_BLOCK StatusBlock,IN PDEVICE_OBJECT DeviceObject)209 CPortFilterWavePci::FastDeviceIoControl(
210 IN PFILE_OBJECT FileObject,
211 IN BOOLEAN Wait,
212 IN PVOID InputBuffer,
213 IN ULONG InputBufferLength,
214 OUT PVOID OutputBuffer,
215 IN ULONG OutputBufferLength,
216 IN ULONG IoControlCode,
217 OUT PIO_STATUS_BLOCK StatusBlock,
218 IN PDEVICE_OBJECT DeviceObject)
219 {
220 return FALSE;
221 }
222
223 BOOLEAN
224 NTAPI
FastRead(IN PFILE_OBJECT FileObject,IN PLARGE_INTEGER FileOffset,IN ULONG Length,IN BOOLEAN Wait,IN ULONG LockKey,IN PVOID Buffer,OUT PIO_STATUS_BLOCK StatusBlock,IN PDEVICE_OBJECT DeviceObject)225 CPortFilterWavePci::FastRead(
226 IN PFILE_OBJECT FileObject,
227 IN PLARGE_INTEGER FileOffset,
228 IN ULONG Length,
229 IN BOOLEAN Wait,
230 IN ULONG LockKey,
231 IN PVOID Buffer,
232 OUT PIO_STATUS_BLOCK StatusBlock,
233 IN PDEVICE_OBJECT DeviceObject)
234 {
235 return FALSE;
236 }
237
238 BOOLEAN
239 NTAPI
FastWrite(IN PFILE_OBJECT FileObject,IN PLARGE_INTEGER FileOffset,IN ULONG Length,IN BOOLEAN Wait,IN ULONG LockKey,IN PVOID Buffer,OUT PIO_STATUS_BLOCK StatusBlock,IN PDEVICE_OBJECT DeviceObject)240 CPortFilterWavePci::FastWrite(
241 IN PFILE_OBJECT FileObject,
242 IN PLARGE_INTEGER FileOffset,
243 IN ULONG Length,
244 IN BOOLEAN Wait,
245 IN ULONG LockKey,
246 IN PVOID Buffer,
247 OUT PIO_STATUS_BLOCK StatusBlock,
248 IN PDEVICE_OBJECT DeviceObject)
249 {
250 return FALSE;
251 }
252
253 NTSTATUS
254 NTAPI
Init(IN IPortWavePci * Port)255 CPortFilterWavePci::Init(
256 IN IPortWavePci* Port)
257 {
258 ISubdevice * ISubDevice;
259 SUBDEVICE_DESCRIPTOR * Descriptor;
260 NTSTATUS Status;
261
262 m_Port = Port;
263
264 // get our private interface
265 Status = m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&ISubDevice);
266 if (!NT_SUCCESS(Status))
267 return STATUS_UNSUCCESSFUL;
268
269 // get the subdevice descriptor
270 Status = ISubDevice->GetDescriptor(&Descriptor);
271
272 // release subdevice interface
273 ISubDevice->Release();
274
275 if (!NT_SUCCESS(Status))
276 return STATUS_UNSUCCESSFUL;
277
278 // save descriptor
279 m_Descriptor = Descriptor;
280
281 // allocate pin array
282 m_Pins = (IPortPinWavePci**)AllocateItem(NonPagedPool, Descriptor->Factory.PinDescriptorCount * sizeof(IPortPinWavePci*), TAG_PORTCLASS);
283
284 if (!m_Pins)
285 return STATUS_UNSUCCESSFUL;
286
287 // increment reference count
288 Port->AddRef();
289
290 return STATUS_SUCCESS;
291 }
292
293 NTSTATUS
294 NTAPI
FreePin(IN struct IPortPinWavePci * Pin)295 CPortFilterWavePci::FreePin(
296 IN struct IPortPinWavePci* Pin)
297 {
298 ULONG Index;
299
300 for(Index = 0; Index < m_Descriptor->Factory.PinDescriptorCount; Index++)
301 {
302 if (m_Pins[Index] == Pin)
303 {
304 m_Descriptor->Factory.Instances[Index].CurrentPinInstanceCount--;
305 m_Pins[Index] = NULL;
306 return STATUS_SUCCESS;
307 }
308 }
309 return STATUS_UNSUCCESSFUL;
310 }
311
312 NTSTATUS
NewPortFilterWavePci(OUT IPortFilterWavePci ** OutFilter)313 NewPortFilterWavePci(
314 OUT IPortFilterWavePci ** OutFilter)
315 {
316 CPortFilterWavePci * This;
317
318 This = new(NonPagedPool, TAG_PORTCLASS)CPortFilterWavePci(NULL);
319 if (!This)
320 return STATUS_INSUFFICIENT_RESOURCES;
321
322 This->AddRef();
323
324 // return result
325 *OutFilter = (IPortFilterWavePci*)This;
326
327 return STATUS_SUCCESS;
328 }
329