Merge trunk head (r43756)
[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] && m_Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount)
100 {
101 // release existing instance
102 PC_ASSERT(0);
103 m_Pins[ConnectDetails->PinId]->Close(DeviceObject, NULL);
104 }
105
106 // now create the pin
107 Status = NewPortPinWavePci(&Pin);
108 if (!NT_SUCCESS(Status))
109 {
110 return Status;
111 }
112
113 // initialize the pin
114 Status = Pin->Init(m_Port, this, ConnectDetails, &m_Descriptor->Factory.KsPinDescriptor[ConnectDetails->PinId], GetDeviceObjectFromPortWavePci(m_Port));
115 if (!NT_SUCCESS(Status))
116 {
117 Pin->Release();
118 return Status;
119 }
120
121 // store pin
122 m_Pins[ConnectDetails->PinId] = Pin;
123
124 // store result
125 *OutTarget = (IIrpTarget*)Pin;
126
127 // increment current instance count
128 m_Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount++;
129
130 return Status;
131 }
132
133 NTSTATUS
134 NTAPI
135 CPortFilterWavePci::DeviceIoControl(
136 IN PDEVICE_OBJECT DeviceObject,
137 IN PIRP Irp)
138 {
139 PIO_STACK_LOCATION IoStack;
140 NTSTATUS Status;
141
142 IoStack = IoGetCurrentIrpStackLocation(Irp);
143
144 if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY)
145 {
146 DPRINT("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength);
147
148 Irp->IoStatus.Status = STATUS_SUCCESS;
149
150 IoCompleteRequest(Irp, IO_NO_INCREMENT);
151 return STATUS_SUCCESS;
152 }
153
154 Status = PcHandlePropertyWithTable(Irp, m_Descriptor->FilterPropertySetCount, m_Descriptor->FilterPropertySet, m_Descriptor);
155 if (Status != STATUS_PENDING)
156 {
157 Irp->IoStatus.Status = Status;
158 DPRINT("Result %x Length %u\n", Status, Irp->IoStatus.Information);
159 IoCompleteRequest(Irp, IO_NO_INCREMENT);
160 }
161 return Status;
162 }
163
164 NTSTATUS
165 NTAPI
166 CPortFilterWavePci::Read(
167 IN PDEVICE_OBJECT DeviceObject,
168 IN PIRP Irp)
169 {
170 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
171 }
172
173 NTSTATUS
174 NTAPI
175 CPortFilterWavePci::Write(
176 IN PDEVICE_OBJECT DeviceObject,
177 IN PIRP Irp)
178 {
179 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
180 }
181
182 NTSTATUS
183 NTAPI
184 CPortFilterWavePci::Flush(
185 IN PDEVICE_OBJECT DeviceObject,
186 IN PIRP Irp)
187 {
188 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
189 }
190
191 NTSTATUS
192 NTAPI
193 CPortFilterWavePci::Close(
194 IN PDEVICE_OBJECT DeviceObject,
195 IN PIRP Irp)
196 {
197 Irp->IoStatus.Status = STATUS_SUCCESS;
198 Irp->IoStatus.Information = 0;
199 IoCompleteRequest(Irp, IO_NO_INCREMENT);
200
201 return STATUS_UNSUCCESSFUL;
202 }
203
204 NTSTATUS
205 NTAPI
206 CPortFilterWavePci::QuerySecurity(
207 IN PDEVICE_OBJECT DeviceObject,
208 IN PIRP Irp)
209 {
210 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
211 }
212
213 NTSTATUS
214 NTAPI
215 CPortFilterWavePci::SetSecurity(
216 IN PDEVICE_OBJECT DeviceObject,
217 IN PIRP Irp)
218 {
219 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
220 }
221
222 BOOLEAN
223 NTAPI
224 CPortFilterWavePci::FastDeviceIoControl(
225 IN PFILE_OBJECT FileObject,
226 IN BOOLEAN Wait,
227 IN PVOID InputBuffer,
228 IN ULONG InputBufferLength,
229 OUT PVOID OutputBuffer,
230 IN ULONG OutputBufferLength,
231 IN ULONG IoControlCode,
232 OUT PIO_STATUS_BLOCK StatusBlock,
233 IN PDEVICE_OBJECT DeviceObject)
234 {
235 return FALSE;
236 }
237
238 BOOLEAN
239 NTAPI
240 CPortFilterWavePci::FastRead(
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 BOOLEAN
254 NTAPI
255 CPortFilterWavePci::FastWrite(
256 IN PFILE_OBJECT FileObject,
257 IN PLARGE_INTEGER FileOffset,
258 IN ULONG Length,
259 IN BOOLEAN Wait,
260 IN ULONG LockKey,
261 IN PVOID Buffer,
262 OUT PIO_STATUS_BLOCK StatusBlock,
263 IN PDEVICE_OBJECT DeviceObject)
264 {
265 return FALSE;
266 }
267
268 NTSTATUS
269 NTAPI
270 CPortFilterWavePci::Init(
271 IN IPortWavePci* Port)
272 {
273 ISubdevice * ISubDevice;
274 SUBDEVICE_DESCRIPTOR * Descriptor;
275 NTSTATUS Status;
276
277 m_Port = Port;
278
279 // get our private interface
280 Status = m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&ISubDevice);
281 if (!NT_SUCCESS(Status))
282 return STATUS_UNSUCCESSFUL;
283
284 // get the subdevice descriptor
285 Status = ISubDevice->GetDescriptor(&Descriptor);
286
287 // release subdevice interface
288 ISubDevice->Release();
289
290 if (!NT_SUCCESS(Status))
291 return STATUS_UNSUCCESSFUL;
292
293 // save descriptor
294 m_Descriptor = Descriptor;
295
296 // allocate pin array
297 m_Pins = (IPortPinWavePci**)AllocateItem(NonPagedPool, Descriptor->Factory.PinDescriptorCount * sizeof(IPortPinWavePci*), TAG_PORTCLASS);
298
299 if (!m_Pins)
300 return STATUS_UNSUCCESSFUL;
301
302 // increment reference count
303 Port->AddRef();
304
305 return STATUS_SUCCESS;
306 }
307
308 NTSTATUS
309 NewPortFilterWavePci(
310 OUT IPortFilterWavePci ** OutFilter)
311 {
312 CPortFilterWavePci * This;
313
314 This = new(NonPagedPool, TAG_PORTCLASS)CPortFilterWavePci(NULL);
315 if (!This)
316 return STATUS_INSUFFICIENT_RESOURCES;
317
318 This->AddRef();
319
320 // return result
321 *OutFilter = (IPortFilterWavePci*)This;
322
323 return STATUS_SUCCESS;
324 }