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
;
139 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
141 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
)
143 DPRINT1("Unhandled function %lx Length %x\n", IoStack
->Parameters
.DeviceIoControl
.IoControlCode
, IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
);
145 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
147 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
148 return STATUS_SUCCESS
;
151 PC_ASSERT(IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
);
153 return PcPropertyHandler(Irp
, m_Descriptor
);
158 CPortFilterWaveCyclic::Read(
159 IN PDEVICE_OBJECT DeviceObject
,
162 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
167 CPortFilterWaveCyclic::Write(
168 IN PDEVICE_OBJECT DeviceObject
,
171 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
176 CPortFilterWaveCyclic::Flush(
177 IN PDEVICE_OBJECT DeviceObject
,
180 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
185 CPortFilterWaveCyclic::Close(
186 IN PDEVICE_OBJECT DeviceObject
,
190 NTSTATUS Status
= STATUS_SUCCESS
;
195 for(Index
= 0; Index
< m_Descriptor
->Factory
.PinDescriptorCount
; Index
++)
197 // all pins should have been closed by now
198 ASSERT(m_Pins
[Index
] == NULL
);
201 // release reference to port
202 m_SubDevice
->Release(m_SubDevice
);
204 // time to shutdown the audio system
205 Status
= m_SubDevice
->ReleaseChildren(m_SubDevice
);
209 Irp
->IoStatus
.Status
= Status
;
210 Irp
->IoStatus
.Information
= 0;
211 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
213 return STATUS_SUCCESS
;
218 CPortFilterWaveCyclic::QuerySecurity(
219 IN PDEVICE_OBJECT DeviceObject
,
222 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
227 CPortFilterWaveCyclic::SetSecurity(
228 IN PDEVICE_OBJECT DeviceObject
,
231 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
236 CPortFilterWaveCyclic::FastDeviceIoControl(
237 IN PFILE_OBJECT FileObject
,
239 IN PVOID InputBuffer
,
240 IN ULONG InputBufferLength
,
241 OUT PVOID OutputBuffer
,
242 IN ULONG OutputBufferLength
,
243 IN ULONG IoControlCode
,
244 OUT PIO_STATUS_BLOCK StatusBlock
,
245 IN PDEVICE_OBJECT DeviceObject
)
247 return KsDispatchFastIoDeviceControlFailure(FileObject
, Wait
, InputBuffer
, InputBufferLength
, OutputBuffer
, OutputBufferLength
, IoControlCode
, StatusBlock
, DeviceObject
);
252 CPortFilterWaveCyclic::FastRead(
253 IN PFILE_OBJECT FileObject
,
254 IN PLARGE_INTEGER FileOffset
,
259 OUT PIO_STATUS_BLOCK StatusBlock
,
260 IN PDEVICE_OBJECT DeviceObject
)
268 CPortFilterWaveCyclic::FastWrite(
269 IN PFILE_OBJECT FileObject
,
270 IN PLARGE_INTEGER FileOffset
,
275 OUT PIO_STATUS_BLOCK StatusBlock
,
276 IN PDEVICE_OBJECT DeviceObject
)
284 CPortFilterWaveCyclic::Init(
285 IN IPortWaveCyclic
* Port
)
287 ISubdevice
* ISubDevice
;
288 SUBDEVICE_DESCRIPTOR
* Descriptor
;
291 // get our private interface
292 Status
= Port
->QueryInterface(IID_ISubdevice
, (PVOID
*)&ISubDevice
);
293 if (!NT_SUCCESS(Status
))
294 return STATUS_UNSUCCESSFUL
;
296 // get the subdevice descriptor
297 Status
= ISubDevice
->GetDescriptor(&Descriptor
);
299 // store subdevice interface
300 m_SubDevice
= ISubDevice
;
302 if (!NT_SUCCESS(Status
))
303 return STATUS_UNSUCCESSFUL
;
306 m_Descriptor
= Descriptor
;
308 // allocate pin array
309 m_Pins
= (IPortPinWaveCyclic
**)AllocateItem(NonPagedPool
, Descriptor
->Factory
.PinDescriptorCount
* sizeof(IPortPinWaveCyclic
*), TAG_PORTCLASS
);
312 return STATUS_UNSUCCESSFUL
;
317 return STATUS_SUCCESS
;
323 CPortFilterWaveCyclic::FreePin(
324 IN
struct IPortPinWaveCyclic
* Pin
)
328 for(Index
= 0; Index
< m_Descriptor
->Factory
.PinDescriptorCount
; Index
++)
330 if (m_Pins
[Index
] == Pin
)
332 m_Descriptor
->Factory
.Instances
[Index
].CurrentPinInstanceCount
--;
333 m_Pins
[Index
]->Release();
334 m_Pins
[Index
] = NULL
;
335 return STATUS_SUCCESS
;
338 return STATUS_UNSUCCESSFUL
;
343 NewPortFilterWaveCyclic(
344 OUT IPortFilterWaveCyclic
** OutFilter
)
346 CPortFilterWaveCyclic
* This
;
348 This
= new(NonPagedPool
, TAG_PORTCLASS
)CPortFilterWaveCyclic(NULL
);
351 return STATUS_INSUFFICIENT_RESOURCES
;
356 *OutFilter
= (IPortFilterWaveCyclic
*)This
;
358 return STATUS_SUCCESS
;