mirror of
https://github.com/reactos/reactos.git
synced 2024-09-19 09:09:53 +00:00
e1ef078741
The idea then would be to have the following behaviour (when specifying the following options in the kernel command line): /DEBUGPORT=COMi --> load KDCOM.DLL and use COMi port (i == 1,2,3,4) if possible. /DEBUGPORT=FOO --> load KDFOO.DLL (useful for KDUSB.DLL, KD1394.DLL, KDBAZIS.DLL for VirtualKD, etc...) /DEBUGPORT=ROSDBG:[COMi|SCREEN|FILE|GDB|...] --> load KDROSDBG.DLL which contains the ROS kernel debugger, and use COMi or SCREEN or... as output port. svn path=/branches/kd++/; revision=58883
366 lines
8.4 KiB
C++
366 lines
8.4 KiB
C++
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS Kernel Streaming
|
|
* FILE: drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c
|
|
* PURPOSE: portcls wave cyclic filter
|
|
* PROGRAMMER: Johannes Anderwald
|
|
*/
|
|
|
|
#include "private.hpp"
|
|
|
|
class CPortFilterWaveCyclic : public IPortFilterWaveCyclic
|
|
{
|
|
public:
|
|
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
|
|
|
|
STDMETHODIMP_(ULONG) AddRef()
|
|
{
|
|
InterlockedIncrement(&m_Ref);
|
|
return m_Ref;
|
|
}
|
|
STDMETHODIMP_(ULONG) Release()
|
|
{
|
|
InterlockedDecrement(&m_Ref);
|
|
|
|
if (!m_Ref)
|
|
{
|
|
delete this;
|
|
return 0;
|
|
}
|
|
return m_Ref;
|
|
}
|
|
IMP_IPortFilterWaveCyclic;
|
|
CPortFilterWaveCyclic(IUnknown *OuterUnknown){}
|
|
virtual ~CPortFilterWaveCyclic(){}
|
|
|
|
protected:
|
|
IPortWaveCyclic* m_Port;
|
|
IPortPinWaveCyclic ** m_Pins;
|
|
SUBDEVICE_DESCRIPTOR * m_Descriptor;
|
|
ISubdevice * m_SubDevice;
|
|
LONG m_Ref;
|
|
};
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CPortFilterWaveCyclic::QueryInterface(
|
|
IN REFIID refiid,
|
|
OUT PVOID* Output)
|
|
{
|
|
if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) ||
|
|
IsEqualGUIDAligned(refiid, IID_IUnknown))
|
|
{
|
|
*Output = PVOID(PUNKNOWN(this));
|
|
PUNKNOWN(*Output)->AddRef();
|
|
return STATUS_SUCCESS;
|
|
}
|
|
else if (IsEqualGUIDAligned(refiid, IID_IPort))
|
|
{
|
|
*Output = PUNKNOWN(m_Port);
|
|
PUNKNOWN(*Output)->AddRef();
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CPortFilterWaveCyclic::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)
|
|
{
|
|
NTSTATUS Status;
|
|
IPortPinWaveCyclic * Pin;
|
|
PKSPIN_CONNECT ConnectDetails;
|
|
|
|
#if 0
|
|
ASSERT(m_Port);
|
|
ASSERT(m_Descriptor);
|
|
ASSERT(m_Pins);
|
|
#endif
|
|
|
|
DPRINT("CPortFilterWaveCyclic::NewIrpTarget entered\n");
|
|
|
|
// let's verify the connection request
|
|
Status = PcValidateConnectRequest(Irp, &m_Descriptor->Factory, &ConnectDetails);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
if (m_Pins[ConnectDetails->PinId] &&
|
|
(m_Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount == m_Descriptor->Factory.Instances[ConnectDetails->PinId].MaxFilterInstanceCount))
|
|
{
|
|
// release existing instance
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
// now create the pin
|
|
Status = NewPortPinWaveCyclic(&Pin);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return Status;
|
|
}
|
|
|
|
// initialize the pin
|
|
Status = Pin->Init(m_Port, this, ConnectDetails, &m_Descriptor->Factory.KsPinDescriptor[ConnectDetails->PinId]);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
Pin->Release();
|
|
return Status;
|
|
}
|
|
|
|
// store pin
|
|
m_Pins[ConnectDetails->PinId] = Pin;
|
|
|
|
// store result
|
|
*OutTarget = (IIrpTarget*)Pin;
|
|
|
|
// increment current instance count
|
|
m_Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount++;
|
|
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CPortFilterWaveCyclic::DeviceIoControl(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp)
|
|
{
|
|
PIO_STACK_LOCATION IoStack;
|
|
NTSTATUS Status;
|
|
|
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY)
|
|
{
|
|
DPRINT("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength);
|
|
|
|
Irp->IoStatus.Status = STATUS_NOT_FOUND;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_NOT_FOUND;
|
|
}
|
|
|
|
Status = PcHandlePropertyWithTable(Irp, m_Descriptor->FilterPropertySetCount, m_Descriptor->FilterPropertySet, m_Descriptor);
|
|
if (Status != STATUS_PENDING)
|
|
{
|
|
Irp->IoStatus.Status = Status;
|
|
DPRINT("Result %x Length %u\n", Status, Irp->IoStatus.Information);
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CPortFilterWaveCyclic::Read(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp)
|
|
{
|
|
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CPortFilterWaveCyclic::Write(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp)
|
|
{
|
|
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CPortFilterWaveCyclic::Flush(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp)
|
|
{
|
|
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CPortFilterWaveCyclic::Close(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp)
|
|
{
|
|
//ULONG Index;
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
#if 0
|
|
if (m_ref == 1)
|
|
{
|
|
for(Index = 0; Index < m_Descriptor->Factory.PinDescriptorCount; Index++)
|
|
{
|
|
// all pins should have been closed by now
|
|
ASSERT(m_Pins[Index] == NULL);
|
|
}
|
|
|
|
// release reference to port
|
|
m_SubDevice->Release(m_SubDevice);
|
|
|
|
// time to shutdown the audio system
|
|
Status = m_SubDevice->ReleaseChildren(m_SubDevice);
|
|
}
|
|
#endif
|
|
|
|
Irp->IoStatus.Status = Status;
|
|
Irp->IoStatus.Information = 0;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CPortFilterWaveCyclic::QuerySecurity(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp)
|
|
{
|
|
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CPortFilterWaveCyclic::SetSecurity(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp)
|
|
{
|
|
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
|
|
}
|
|
|
|
BOOLEAN
|
|
NTAPI
|
|
CPortFilterWaveCyclic::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)
|
|
{
|
|
return KsDispatchFastIoDeviceControlFailure(FileObject, Wait, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, IoControlCode, StatusBlock, DeviceObject);
|
|
}
|
|
|
|
BOOLEAN
|
|
NTAPI
|
|
CPortFilterWaveCyclic::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)
|
|
{
|
|
UNIMPLEMENTED
|
|
return FALSE;
|
|
}
|
|
|
|
BOOLEAN
|
|
NTAPI
|
|
CPortFilterWaveCyclic::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)
|
|
{
|
|
UNIMPLEMENTED
|
|
return FALSE;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CPortFilterWaveCyclic::Init(
|
|
IN IPortWaveCyclic* Port)
|
|
{
|
|
ISubdevice * ISubDevice;
|
|
SUBDEVICE_DESCRIPTOR * Descriptor;
|
|
NTSTATUS Status;
|
|
|
|
// get our private interface
|
|
Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&ISubDevice);
|
|
if (!NT_SUCCESS(Status))
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
// get the subdevice descriptor
|
|
Status = ISubDevice->GetDescriptor(&Descriptor);
|
|
|
|
// store subdevice interface
|
|
m_SubDevice = ISubDevice;
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
// save descriptor
|
|
m_Descriptor = Descriptor;
|
|
|
|
// allocate pin array
|
|
m_Pins = (IPortPinWaveCyclic**)AllocateItem(NonPagedPool, Descriptor->Factory.PinDescriptorCount * sizeof(IPortPinWaveCyclic*), TAG_PORTCLASS);
|
|
|
|
if (!m_Pins)
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
// store port driver
|
|
m_Port = Port;
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CPortFilterWaveCyclic::FreePin(
|
|
IN PPORTPINWAVECYCLIC Pin)
|
|
{
|
|
ULONG Index;
|
|
|
|
for(Index = 0; Index < m_Descriptor->Factory.PinDescriptorCount; Index++)
|
|
{
|
|
if (m_Pins[Index] == Pin)
|
|
{
|
|
m_Descriptor->Factory.Instances[Index].CurrentPinInstanceCount--;
|
|
m_Pins[Index] = NULL;
|
|
return STATUS_SUCCESS;
|
|
}
|
|
}
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
NewPortFilterWaveCyclic(
|
|
OUT IPortFilterWaveCyclic ** OutFilter)
|
|
{
|
|
CPortFilterWaveCyclic * This;
|
|
|
|
This = new(NonPagedPool, TAG_PORTCLASS)CPortFilterWaveCyclic(NULL);
|
|
|
|
if (!This)
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
This->AddRef();
|
|
|
|
// return result
|
|
*OutFilter = (IPortFilterWaveCyclic*)This;
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|