2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c
5 * PURPOSE: portcls wave cyclic filter
6 * PROGRAMMER: Johannes Anderwald
11 class CPortFilterWaveCyclic
: public IPortFilterWaveCyclic
14 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
16 STDMETHODIMP_(ULONG
) AddRef()
18 InterlockedIncrement(&m_Ref
);
21 STDMETHODIMP_(ULONG
) Release()
23 InterlockedDecrement(&m_Ref
);
32 IMP_IPortFilterWaveCyclic
;
33 CPortFilterWaveCyclic(IUnknown
*OuterUnknown
){}
34 virtual ~CPortFilterWaveCyclic(){}
37 IPortWaveCyclic
* m_Port
;
38 IPortPinWaveCyclic
** m_Pins
;
39 SUBDEVICE_DESCRIPTOR
* m_Descriptor
;
40 ISubdevice
* m_SubDevice
;
46 CPortFilterWaveCyclic::QueryInterface(
50 if (IsEqualGUIDAligned(refiid
, IID_IIrpTarget
) ||
51 IsEqualGUIDAligned(refiid
, IID_IUnknown
))
53 *Output
= PVOID(PUNKNOWN(this));
54 PUNKNOWN(*Output
)->AddRef();
55 return STATUS_SUCCESS
;
57 else if (IsEqualGUIDAligned(refiid
, IID_IPort
))
59 *Output
= PUNKNOWN(m_Port
);
60 PUNKNOWN(*Output
)->AddRef();
61 return STATUS_SUCCESS
;
64 return STATUS_UNSUCCESSFUL
;
69 CPortFilterWaveCyclic::NewIrpTarget(
70 OUT
struct IIrpTarget
**OutTarget
,
73 IN POOL_TYPE PoolType
,
74 IN PDEVICE_OBJECT DeviceObject
,
76 IN KSOBJECT_CREATE
*CreateObject
)
79 IPortPinWaveCyclic
* Pin
;
80 PKSPIN_CONNECT ConnectDetails
;
88 DPRINT("CPortFilterWaveCyclic::NewIrpTarget entered\n");
90 // let's verify the connection request
91 Status
= PcValidateConnectRequest(Irp
, &m_Descriptor
->Factory
, &ConnectDetails
);
92 if (!NT_SUCCESS(Status
))
94 return STATUS_UNSUCCESSFUL
;
97 if (m_Pins
[ConnectDetails
->PinId
] &&
98 (m_Descriptor
->Factory
.Instances
[ConnectDetails
->PinId
].CurrentPinInstanceCount
== m_Descriptor
->Factory
.Instances
[ConnectDetails
->PinId
].MaxFilterInstanceCount
))
100 // release existing instance
101 return STATUS_UNSUCCESSFUL
;
104 // now create the pin
105 Status
= NewPortPinWaveCyclic(&Pin
);
106 if (!NT_SUCCESS(Status
))
111 // initialize the pin
112 Status
= Pin
->Init(m_Port
, this, ConnectDetails
, &m_Descriptor
->Factory
.KsPinDescriptor
[ConnectDetails
->PinId
]);
113 if (!NT_SUCCESS(Status
))
120 m_Pins
[ConnectDetails
->PinId
] = Pin
;
123 *OutTarget
= (IIrpTarget
*)Pin
;
125 // increment current instance count
126 m_Descriptor
->Factory
.Instances
[ConnectDetails
->PinId
].CurrentPinInstanceCount
++;
133 CPortFilterWaveCyclic::DeviceIoControl(
134 IN PDEVICE_OBJECT DeviceObject
,
137 PIO_STACK_LOCATION IoStack
;
140 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
142 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
)
144 DPRINT("Unhandled function %lx Length %x\n", IoStack
->Parameters
.DeviceIoControl
.IoControlCode
, IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
);
146 Irp
->IoStatus
.Status
= STATUS_NOT_FOUND
;
148 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
149 return STATUS_NOT_FOUND
;
152 Status
= PcHandlePropertyWithTable(Irp
, m_Descriptor
->FilterPropertySetCount
, m_Descriptor
->FilterPropertySet
, m_Descriptor
);
153 if (Status
!= STATUS_PENDING
)
155 Irp
->IoStatus
.Status
= Status
;
156 DPRINT("Result %x Length %u\n", Status
, Irp
->IoStatus
.Information
);
157 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
164 CPortFilterWaveCyclic::Read(
165 IN PDEVICE_OBJECT DeviceObject
,
168 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
173 CPortFilterWaveCyclic::Write(
174 IN PDEVICE_OBJECT DeviceObject
,
177 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
182 CPortFilterWaveCyclic::Flush(
183 IN PDEVICE_OBJECT DeviceObject
,
186 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
191 CPortFilterWaveCyclic::Close(
192 IN PDEVICE_OBJECT DeviceObject
,
196 NTSTATUS Status
= STATUS_SUCCESS
;
201 for(Index
= 0; Index
< m_Descriptor
->Factory
.PinDescriptorCount
; Index
++)
203 // all pins should have been closed by now
204 ASSERT(m_Pins
[Index
] == NULL
);
207 // release reference to port
208 m_SubDevice
->Release(m_SubDevice
);
210 // time to shutdown the audio system
211 Status
= m_SubDevice
->ReleaseChildren(m_SubDevice
);
215 Irp
->IoStatus
.Status
= Status
;
216 Irp
->IoStatus
.Information
= 0;
217 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
219 return STATUS_SUCCESS
;
224 CPortFilterWaveCyclic::QuerySecurity(
225 IN PDEVICE_OBJECT DeviceObject
,
228 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
233 CPortFilterWaveCyclic::SetSecurity(
234 IN PDEVICE_OBJECT DeviceObject
,
237 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
242 CPortFilterWaveCyclic::FastDeviceIoControl(
243 IN PFILE_OBJECT FileObject
,
245 IN PVOID InputBuffer
,
246 IN ULONG InputBufferLength
,
247 OUT PVOID OutputBuffer
,
248 IN ULONG OutputBufferLength
,
249 IN ULONG IoControlCode
,
250 OUT PIO_STATUS_BLOCK StatusBlock
,
251 IN PDEVICE_OBJECT DeviceObject
)
253 return KsDispatchFastIoDeviceControlFailure(FileObject
, Wait
, InputBuffer
, InputBufferLength
, OutputBuffer
, OutputBufferLength
, IoControlCode
, StatusBlock
, DeviceObject
);
258 CPortFilterWaveCyclic::FastRead(
259 IN PFILE_OBJECT FileObject
,
260 IN PLARGE_INTEGER FileOffset
,
265 OUT PIO_STATUS_BLOCK StatusBlock
,
266 IN PDEVICE_OBJECT DeviceObject
)
274 CPortFilterWaveCyclic::FastWrite(
275 IN PFILE_OBJECT FileObject
,
276 IN PLARGE_INTEGER FileOffset
,
281 OUT PIO_STATUS_BLOCK StatusBlock
,
282 IN PDEVICE_OBJECT DeviceObject
)
290 CPortFilterWaveCyclic::Init(
291 IN IPortWaveCyclic
* Port
)
293 ISubdevice
* ISubDevice
;
294 SUBDEVICE_DESCRIPTOR
* Descriptor
;
297 // get our private interface
298 Status
= Port
->QueryInterface(IID_ISubdevice
, (PVOID
*)&ISubDevice
);
299 if (!NT_SUCCESS(Status
))
300 return STATUS_UNSUCCESSFUL
;
302 // get the subdevice descriptor
303 Status
= ISubDevice
->GetDescriptor(&Descriptor
);
305 // store subdevice interface
306 m_SubDevice
= ISubDevice
;
308 if (!NT_SUCCESS(Status
))
309 return STATUS_UNSUCCESSFUL
;
312 m_Descriptor
= Descriptor
;
314 // allocate pin array
315 m_Pins
= (IPortPinWaveCyclic
**)AllocateItem(NonPagedPool
, Descriptor
->Factory
.PinDescriptorCount
* sizeof(IPortPinWaveCyclic
*), TAG_PORTCLASS
);
318 return STATUS_UNSUCCESSFUL
;
323 return STATUS_SUCCESS
;
329 CPortFilterWaveCyclic::FreePin(
330 IN
struct IPortPinWaveCyclic
* Pin
)
334 for(Index
= 0; Index
< m_Descriptor
->Factory
.PinDescriptorCount
; Index
++)
336 if (m_Pins
[Index
] == Pin
)
338 m_Descriptor
->Factory
.Instances
[Index
].CurrentPinInstanceCount
--;
339 m_Pins
[Index
] = NULL
;
340 return STATUS_SUCCESS
;
343 return STATUS_UNSUCCESSFUL
;
348 NewPortFilterWaveCyclic(
349 OUT IPortFilterWaveCyclic
** OutFilter
)
351 CPortFilterWaveCyclic
* This
;
353 This
= new(NonPagedPool
, TAG_PORTCLASS
)CPortFilterWaveCyclic(NULL
);
356 return STATUS_INSUFFICIENT_RESOURCES
;
361 *OutFilter
= (IPortFilterWaveCyclic
*)This
;
363 return STATUS_SUCCESS
;