Author: janderwald
Date: Sat Oct 23 12:10:56 2010
New Revision: 49238
URL:
http://svn.reactos.org/svn/reactos?rev=49238&view=rev
Log:
[PORTCLS]
- Fix check if the pin can be instantiated another time
- Remove hack to close old
- Add function FreePin to remove its old reference
- Fix memory leaks / reference leaks in WavePci pin implementation
- Fix memory / reference leaks in WavePci Close implementation
Modified:
trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.cpp
trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.cpp
trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp
trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp
trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp
trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.cpp [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.cpp [iso-8859-1] Sat
Oct 23 12:10:56 2010
@@ -327,7 +327,7 @@
NTSTATUS
NTAPI
CPortFilterWaveCyclic::FreePin(
- IN struct IPortPinWaveCyclic* Pin)
+ IN PPORTPINWAVECYCLIC Pin)
{
ULONG Index;
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.cpp [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavepci.cpp [iso-8859-1] Sat
Oct 23 12:10:56 2010
@@ -96,12 +96,13 @@
return STATUS_UNSUCCESSFUL;
}
- if (m_Pins[ConnectDetails->PinId] &&
m_Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount)
- {
- // release existing instance
- PC_ASSERT(0);
- m_Pins[ConnectDetails->PinId]->Close(DeviceObject, NULL);
- }
+ if (m_Pins[ConnectDetails->PinId] &&
+
(m_Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount ==
m_Descriptor->Factory.Instances[ConnectDetails->PinId].MaxFilterInstanceCount))
+ {
+ // no available instance
+ return STATUS_UNSUCCESSFUL;
+ }
+
// now create the pin
Status = NewPortPinWavePci(&Pin);
@@ -305,6 +306,26 @@
return STATUS_SUCCESS;
}
+NTSTATUS
+NTAPI
+CPortFilterWavePci::FreePin(
+ IN struct IPortPinWavePci* 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
NewPortFilterWavePci(
OUT IPortFilterWavePci ** OutFilter)
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp [iso-8859-1] Sat Oct 23
12:10:56 2010
@@ -599,6 +599,8 @@
#undef INTERFACE
#define INTERFACE IPortFilterWavePci
+struct IPortPinWavePci;
+
DECLARE_INTERFACE_(IPortFilterWavePci, IIrpTarget)
{
DEFINE_ABSTRACT_UNKNOWN()
@@ -607,6 +609,9 @@
STDMETHOD_(NTSTATUS, Init)(THIS_
IN PPORTWAVEPCI Port)PURE;
+
+ STDMETHOD_(NTSTATUS, FreePin)(THIS_
+ IN struct IPortPinWavePci* Pin)PURE;
};
typedef IPortFilterWavePci *PPORTFILTERWAVEPCI;
@@ -614,7 +619,10 @@
#define IMP_IPortFilterPci \
IMP_IIrpTarget; \
STDMETHODIMP_(NTSTATUS) Init(THIS_ \
- IN PPORTWAVEPCI Port)
+ IN PPORTWAVEPCI Port); \
+ STDMETHODIMP_(NTSTATUS) FreePin(THIS_ \
+ IN struct IPortPinWavePci* Pin)
+
/*****************************************************************************
* IPortPinWavePci
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp [iso-8859-1] Sat
Oct 23 12:10:56 2010
@@ -960,27 +960,29 @@
{
// free format
FreeItem(m_Format, TAG_PORTCLASS);
+
+ // format is freed
m_Format = NULL;
}
if (m_IrpQueue)
{
- // fixme cancel irps
+ // cancel remaining irps
+ m_IrpQueue->CancelBuffers();
+
+ // release irp queue
m_IrpQueue->Release();
- }
-
-
- if (m_Port)
- {
- // release reference to port driver
- m_Port->Release();
- m_Port = NULL;
+
+ // queue is freed
+ m_IrpQueue = NULL;
}
if (m_ServiceGroup)
{
// remove member from service group
m_ServiceGroup->RemoveMember(PSERVICESINK(this));
+
+ // do not release service group, it is released by the miniport object
m_ServiceGroup = NULL;
}
@@ -999,20 +1001,35 @@
// set state to stop
m_State = KSSTATE_STOP;
-
DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql());
+
// release stream
m_Stream->Release();
+ // stream is now freed
+ m_Stream = NULL;
}
if (m_Filter)
{
- // release reference to filter instance
+ // disconnect pin from filter
m_Filter->FreePin((PPORTPINWAVECYCLIC)this);
+
+ // release filter reference
m_Filter->Release();
+
+ // pin is done with filter
m_Filter = NULL;
+ }
+
+ if (m_Port)
+ {
+ // release reference to port driver
+ m_Port->Release();
+
+ // work is done for port
+ m_Port = NULL;
}
Irp->IoStatus.Information = 0;
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp [iso-8859-1] Sat Oct
23 12:10:56 2010
@@ -61,8 +61,6 @@
ULONG m_TotalPackets;
KSAUDIO_POSITION m_Position;
ULONG m_StopCount;
-
- ULONG m_Delay;
BOOL m_bUsePrefetch;
ULONG m_PrefetchOffset;
@@ -637,41 +635,85 @@
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
- ISubdevice *SubDevice;
NTSTATUS Status;
- PSUBDEVICE_DESCRIPTOR Descriptor;
+
+ if (m_Format)
+ {
+ // free format
+ FreeItem(m_Format, TAG_PORTCLASS);
+
+ // format is freed
+ m_Format = NULL;
+ }
+
+ if (m_IrpQueue)
+ {
+ // cancel remaining irps
+ m_IrpQueue->CancelBuffers();
+
+ // release irp queue
+ m_IrpQueue->Release();
+
+ // queue is freed
+ m_IrpQueue = NULL;
+ }
+
if (m_ServiceGroup)
{
+ // remove member from service group
m_ServiceGroup->RemoveMember(PSERVICESINK(this));
+
+ // do not release service group, it is released by the miniport object
+ m_ServiceGroup = NULL;
}
if (m_Stream)
{
if (m_State != KSSTATE_STOP)
{
- m_Stream->SetState(KSSTATE_STOP);
+ // stop stream
+ Status = m_Stream->SetState(KSSTATE_STOP);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Warning: failed to stop stream with %x\n", Status);
+ PC_ASSERT(0);
+ }
}
+ // set state to stop
+ m_State = KSSTATE_STOP;
+
+ DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql());
+
+ // release stream
m_Stream->Release();
- }
-
- Status = m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&SubDevice);
- if (NT_SUCCESS(Status))
- {
- Status = SubDevice->GetDescriptor(&Descriptor);
- if (NT_SUCCESS(Status))
- {
-
Descriptor->Factory.Instances[m_ConnectDetails->PinId].CurrentPinInstanceCount--;
- }
- SubDevice->Release();
- }
-
- if (m_Format)
- {
- FreeItem(m_Format, TAG_PORTCLASS);
- m_Format = NULL;
- }
-
+
+ // stream is now freed
+ m_Stream = NULL;
+ }
+
+ if (m_Filter)
+ {
+ // disconnect pin from filter
+ m_Filter->FreePin((PPORTPINWAVEPCI)this);
+
+ // release filter reference
+ m_Filter->Release();
+
+ // pin is done with filter
+ m_Filter = NULL;
+ }
+
+ if (m_Port)
+ {
+ // release reference to port driver
+ m_Port->Release();
+
+ // work is done for port
+ m_Port = NULL;
+ }
+
+ // successfully complete irp
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
@@ -756,42 +798,66 @@
NTSTATUS Status;
PKSDATAFORMAT DataFormat;
BOOLEAN Capture;
-
+ ISubdevice * Subdevice = NULL;
+ PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL;
+
+ // check if it is a source / sink pin
+ if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK &&
KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN)
+ {
+ // sink pin
+ Capture = FALSE;
+ }
+ else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK &&
KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT)
+ {
+ // source pin
+ Capture = TRUE;
+ }
+ else
+ {
+ DPRINT("Unexpected Communication %u DataFlow %u\n",
KsPinDescriptor->Communication, KsPinDescriptor->DataFlow);
+ DbgBreakPoint();
+ while(TRUE);
+ }
+
+ // add port / filter reference
Port->AddRef();
Filter->AddRef();
+ // initialize pin
m_Port = Port;
m_Filter = Filter;
m_KsPinDescriptor = KsPinDescriptor;
m_ConnectDetails = ConnectDetails;
m_Miniport = GetWavePciMiniport(Port);
m_DeviceObject = DeviceObject;
-
+ m_State = KSSTATE_STOP;
+ m_Capture = Capture;
+
+ DPRINT("IPortPinWavePci_fnInit entered\n");
+
+ // get dataformat
DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1);
- DPRINT("IPortPinWavePci_fnInit entered\n");
-
+ // allocate data format
m_Format = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize,
TAG_PORTCLASS);
if (!m_Format)
+ {
+ // release references
+ m_Port->Release();
+ m_Filter->Release();
+
+ // no dangling pointers
+ Port = NULL;
+ Filter = NULL;
+
+ // failed to allocate data format
return STATUS_INSUFFICIENT_RESOURCES;
-
+ }
+
+ // copy data format
RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize);
- if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK &&
KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN)
- {
- Capture = FALSE;
- }
- else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK &&
KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT)
- {
- Capture = TRUE;
- }
- else
- {
- DPRINT("Unexpected Communication %u DataFlow %u\n",
KsPinDescriptor->Communication, KsPinDescriptor->DataFlow);
- DbgBreakPoint();
- while(TRUE);
- }
-
+ // allocate new stream
Status = m_Miniport->NewStream(&m_Stream,
NULL,
NonPagedPool,
@@ -805,46 +871,80 @@
DPRINT("IPortPinWavePci_fnInit Status %x\n", Status);
if (!NT_SUCCESS(Status))
+ {
+ // free references
+ Port->Release();
+ Filter->Release();
+
+ // free data format
+ FreeItem(m_Format, TAG_PORTCLASS);
+
+ // no dangling pointers
+ m_Port = NULL;
+ m_Filter = NULL;
+ m_Format = NULL;
+
+ // failed to allocate stream
return Status;
-
- if (m_ServiceGroup)
- {
- Status = m_ServiceGroup->AddMember(PSERVICESINK(this));
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Failed to add pin to service group\n");
- return Status;
- }
- }
-
- // delay of 10 milisec
- m_Delay = Int32x32To64(10, -10000);
-
+ }
+
+ // get allocator requirements for pin
Status = m_Stream->GetAllocatorFraming(&m_AllocatorFraming);
+ if (NT_SUCCESS(Status))
+ {
+ DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize
%lu FileAlignment %lu\n",
+ m_AllocatorFraming.OptionsFlags, m_AllocatorFraming.RequirementsFlags,
m_AllocatorFraming.PoolType, m_AllocatorFraming.Frames, m_AllocatorFraming.FrameSize,
m_AllocatorFraming.FileAlignment);
+ }
+
+ // allocate new irp queue
+ Status = NewIrpQueue(&m_IrpQueue);
if (!NT_SUCCESS(Status))
{
- DPRINT("GetAllocatorFraming failed with %x\n", Status);
- }
-
- DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize %lu
FileAlignment %lu\n",
- m_AllocatorFraming.OptionsFlags, m_AllocatorFraming.RequirementsFlags,
m_AllocatorFraming.PoolType, m_AllocatorFraming.Frames, m_AllocatorFraming.FrameSize,
m_AllocatorFraming.FileAlignment);
-
- ISubdevice * Subdevice = NULL;
+ // free references
+ Port->Release();
+ Filter->Release();
+ m_Stream->Release();
+
+ // free data format
+ FreeItem(m_Format, TAG_PORTCLASS);
+
+ // no dangling pointers
+ m_Port = NULL;
+ m_Filter = NULL;
+ m_Format = NULL;
+ m_Stream = NULL;
+
+ // failed to allocate irp queue
+ return Status;
+ }
+
+ // initialize irp queue
+ Status = m_IrpQueue->Init(ConnectDetails, m_AllocatorFraming.FrameSize,
m_AllocatorFraming.FileAlignment, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ // this should never happen
+ ASSERT(0);
+ }
+
// get subdevice interface
Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&Subdevice);
if (!NT_SUCCESS(Status))
- return Status;
-
- PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL;
-
+ {
+ // this function should never fail
+ ASSERT(0);
+ }
+
+ // get subdevice descriptor
Status = Subdevice->GetDescriptor(&SubDeviceDescriptor);
if (!NT_SUCCESS(Status))
{
- // failed to get descriptor
- Subdevice->Release();
- return Status;
- }
+ // this function should never fail
+ ASSERT(0);
+ }
+
+ // release subdevice
+ Subdevice->Release();
/* set up subdevice descriptor */
RtlZeroMemory(&m_Descriptor, sizeof(SUBDEVICE_DESCRIPTOR));
@@ -855,21 +955,30 @@
m_Descriptor.UnknownMiniport = SubDeviceDescriptor->UnknownMiniport;
m_Descriptor.PortPin = (PVOID)this;
-
-
- Status = NewIrpQueue(&m_IrpQueue);
- if (!NT_SUCCESS(Status))
- return Status;
-
- Status = m_IrpQueue->Init(ConnectDetails, m_AllocatorFraming.FrameSize,
m_AllocatorFraming.FileAlignment, NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IrpQueue_Init failed with %x\n", Status);
- return Status;
- }
-
- m_State = KSSTATE_STOP;
- m_Capture = Capture;
+ if (m_ServiceGroup)
+ {
+ Status = m_ServiceGroup->AddMember(PSERVICESINK(this));
+ if (!NT_SUCCESS(Status))
+ {
+ // free references
+ m_Stream->Release();
+ Port->Release();
+ Filter->Release();
+
+ // free data format
+ FreeItem(m_Format, TAG_PORTCLASS);
+
+ // no dangling pointers
+ m_Stream = NULL;
+ m_Port = NULL;
+ m_Filter = NULL;
+ m_Format = NULL;
+
+ // failed to add to service group
+ return Status;
+ }
+ }
+
return STATUS_SUCCESS;
}
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp [iso-8859-1] Sat
Oct 23 12:10:56 2010
@@ -275,12 +275,12 @@
}
// create the subdevice descriptor
- Status = PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor,
+ Status = PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor,
4,
InterfaceGuids,
- 0,
+ 0,
NULL,
- 2,
+ 2,
WaveCyclicPropertySet,
0,
0,