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