Author: janderwald Date: Sun Aug 2 20:20:39 2009 New Revision: 42344
URL: http://svn.reactos.org/svn/reactos?rev=42344&view=rev Log: [PORTCLS] - Fix lots of COM object leaks - IPortWaveCyclic & IPortTopology drivers now shutdown cleanly - Implement freeing of all registered physical connections and release of the registered power management interface [SYSAUDIO] - Close handles to audio filters
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c trunk/reactos/drivers/wdm/audio/backpln/portcls/irp.c trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c trunk/reactos/drivers/wdm/audio/sysaudio/main.c
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c [iso-8859-1] Sun Aug 2 20:20:39 2009 @@ -16,6 +16,7 @@
IPortTopology* Port; SUBDEVICE_DESCRIPTOR * Descriptor; + ISubdevice *SubDevice;
}IPortFilterTopologyImpl;
@@ -112,24 +113,12 @@ IN PIRP Irp) { PIO_STACK_LOCATION IoStack; - ISubdevice *SubDevice = NULL; - SUBDEVICE_DESCRIPTOR * Descriptor; - NTSTATUS Status; IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl *)iface;
IoStack = IoGetCurrentIrpStackLocation(Irp); ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY); - Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&SubDevice); - ASSERT(Status == STATUS_SUCCESS); - ASSERT(SubDevice != NULL); - - Status = SubDevice->lpVtbl->GetDescriptor(SubDevice, &Descriptor); - ASSERT(Status == STATUS_SUCCESS); - ASSERT(Descriptor != NULL); - - SubDevice->lpVtbl->Release(SubDevice); - - return PcPropertyHandler(Irp, Descriptor); + + return PcPropertyHandler(Irp, This->Descriptor); }
/* @@ -181,18 +170,21 @@ IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - //PMINIPORTTOPOLOGY Miniport; - //IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl *)iface; - - /* release reference to port */ - //This->Port->lpVtbl->Release(This->Port); - - /* get the miniport driver */ - //Miniport = GetTopologyMiniport(This->Port); - /* release miniport driver */ - //Miniport->lpVtbl->Release(Miniport); - - Irp->IoStatus.Status = STATUS_SUCCESS; + NTSTATUS Status = STATUS_SUCCESS; + IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl *)iface; + + /* FIXME handle DirectSound */ + + if (This->ref == 1) + { + /* release reference to port */ + This->SubDevice->lpVtbl->Release(This->SubDevice); + + /* time to shutdown the audio system */ + Status = This->SubDevice->lpVtbl->ReleaseChildren(This->SubDevice); + } + + Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT);
@@ -244,9 +236,6 @@ { ULONG Index; PKSPROPERTY Property; - NTSTATUS Status; - ISubdevice * SubDevice = NULL; - PSUBDEVICE_DESCRIPTOR Descriptor = NULL; IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface;
Property = (PKSPROPERTY)InputBuffer; @@ -254,28 +243,14 @@ if (InputBufferLength < sizeof(KSPROPERTY)) return FALSE;
- - /* get private interface */ - Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&SubDevice); - if (!NT_SUCCESS(Status)) - return FALSE; - - /* get descriptor */ - Status = SubDevice->lpVtbl->GetDescriptor(SubDevice, &Descriptor); - if (!NT_SUCCESS(Status)) - { - SubDevice->lpVtbl->Release(SubDevice); - return FALSE; - } - - for(Index = 0; Index < Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++) - { - if (IsEqualGUIDAligned(&Property->Set, Descriptor->FilterPropertySet.Properties[Index].Set)) + for(Index = 0; Index < This->Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++) + { + if (IsEqualGUIDAligned(&Property->Set, This->Descriptor->FilterPropertySet.Properties[Index].Set)) { FastPropertyHandler(FileObject, (PKSPROPERTY)InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, StatusBlock, 1, - &Descriptor->FilterPropertySet.Properties[Index], - Descriptor, SubDevice); + &This->Descriptor->FilterPropertySet.Properties[Index], + This->Descriptor, This->SubDevice); } } return TRUE; @@ -342,17 +317,14 @@ /* get the subdevice descriptor */ Status = ISubDevice->lpVtbl->GetDescriptor(ISubDevice, &Descriptor);
- /* release subdevice interface */ - ISubDevice->lpVtbl->Release(ISubDevice); + /* store subdevice interface */ + This->SubDevice = ISubDevice;
if (!NT_SUCCESS(Status)) return STATUS_UNSUCCESSFUL;
/* save descriptor */ This->Descriptor = Descriptor; - - /* increment reference count */ - Port->lpVtbl->AddRef(Port);
/* store port object */ This->Port = Port;
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c [iso-8859-1] Sun Aug 2 20:20:39 2009 @@ -17,6 +17,7 @@ IPortWaveCyclic* Port; IPortPinWaveCyclic ** Pins; SUBDEVICE_DESCRIPTOR * Descriptor; + ISubdevice * SubDevice;
}IPortFilterWaveCyclicImpl;
@@ -161,24 +162,12 @@ IN PIRP Irp) { PIO_STACK_LOCATION IoStack; - ISubdevice *SubDevice = NULL; - SUBDEVICE_DESCRIPTOR * Descriptor; - NTSTATUS Status; IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl *)iface;
IoStack = IoGetCurrentIrpStackLocation(Irp); ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY); - Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&SubDevice); - ASSERT(Status == STATUS_SUCCESS); - ASSERT(SubDevice != NULL); - - Status = SubDevice->lpVtbl->GetDescriptor(SubDevice, &Descriptor); - ASSERT(Status == STATUS_SUCCESS); - ASSERT(Descriptor != NULL); - - SubDevice->lpVtbl->Release(SubDevice); - - return PcPropertyHandler(Irp, Descriptor); + + return PcPropertyHandler(Irp, This->Descriptor); }
/* @@ -231,7 +220,7 @@ IN PIRP Irp) { ULONG Index; - //PMINIPORTWAVECYCLIC Miniport; + NTSTATUS Status = STATUS_SUCCESS; IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl *)iface;
for(Index = 0; Index < This->Descriptor->Factory.PinDescriptorCount; Index++) @@ -240,16 +229,18 @@ ASSERT(This->Pins[Index] == NULL); }
- /* release reference to port */ - //This->Port->lpVtbl->Release(This->Port); - - /* get the miniport driver */ - //Miniport = GetWaveCyclicMiniport(This->Port); - /* release miniport driver */ - //Miniport->lpVtbl->Release(Miniport); - - - Irp->IoStatus.Status = STATUS_SUCCESS; + DPRINT("IPortFilterWaveCyclic_fnClose ref %u\n", This->ref); + + if (This->ref == 1) + { + /* release reference to port */ + This->SubDevice->lpVtbl->Release(This->SubDevice); + + /* time to shutdown the audio system */ + Status = This->SubDevice->lpVtbl->ReleaseChildren(This->SubDevice); + } + + Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT);
@@ -358,18 +349,16 @@ NTSTATUS Status; IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl*)iface;
- This->Port = Port; - /* get our private interface */ - Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&ISubDevice); + Status = Port->lpVtbl->QueryInterface(Port, &IID_ISubdevice, (PVOID*)&ISubDevice); if (!NT_SUCCESS(Status)) return STATUS_UNSUCCESSFUL;
/* get the subdevice descriptor */ Status = ISubDevice->lpVtbl->GetDescriptor(ISubDevice, &Descriptor);
- /* release subdevice interface */ - ISubDevice->lpVtbl->Release(ISubDevice); + /* store subdevice interface */ + This->SubDevice = ISubDevice;
if (!NT_SUCCESS(Status)) return STATUS_UNSUCCESSFUL; @@ -383,8 +372,8 @@ if (!This->Pins) return STATUS_UNSUCCESSFUL;
- /* increment reference count */ - Port->lpVtbl->AddRef(Port); + /* store port driver */ + This->Port = Port;
return STATUS_SUCCESS; }
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/irp.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/irp.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/irp.c [iso-8859-1] Sun Aug 2 20:20:39 2009 @@ -194,10 +194,39 @@ IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { + PPCLASS_DEVICE_EXTENSION DeviceExtension; + PLIST_ENTRY Entry; + PPHYSICAL_CONNECTION Connection; DPRINT("PortClsShutdown called\n"); - //DbgBreakPoint(); - - /* TODO */ + + /* get device extension */ + DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + while(!IsListEmpty(&DeviceExtension->PhysicalConnectionList)) + { + /* get connection entry */ + Entry = RemoveHeadList(&DeviceExtension->PhysicalConnectionList); + Connection = (PPHYSICAL_CONNECTION)CONTAINING_RECORD(Entry, PHYSICAL_CONNECTION, Entry); + + if (Connection->FromSubDevice) + { + /* release subdevice */ + Connection->FromSubDevice->lpVtbl->Release(Connection->FromSubDevice); + } + + if (Connection->ToSubDevice) + { + /* release subdevice */ + Connection->ToSubDevice->lpVtbl->Release(Connection->ToSubDevice); + } + FreeItem(Connection, TAG_PORTCLASS); + } + + if (DeviceExtension->AdapterPowerManagement) + { + /* release adapter power management */ + DPRINT1("Power %u\n", DeviceExtension->AdapterPowerManagement->lpVtbl->Release(DeviceExtension->AdapterPowerManagement)); + }
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0;
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1] Sun Aug 2 20:20:39 2009 @@ -777,6 +777,12 @@ /* free work item ctx */ FreeItem(Ctx, TAG_PORTCLASS);
+ /* release reference to port driver */ + This->Port->lpVtbl->Release(This->Port); + + /* release reference to filter instance */ + This->Filter->lpVtbl->Release(This->Filter); + if (This->Stream) { Stream = This->Stream; @@ -1013,11 +1019,6 @@
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
- Port->lpVtbl->AddRef(Port); - Filter->lpVtbl->AddRef(Filter); - - This->Port = Port; - This->Filter = Filter; This->KsPinDescriptor = KsPinDescriptor; This->ConnectDetails = ConnectDetails; This->Miniport = GetWaveCyclicMiniport(Port); @@ -1115,11 +1116,18 @@ return Status; }
+ Port->lpVtbl->AddRef(Port); + Filter->lpVtbl->AddRef(Filter); + + This->Port = Port; + This->Filter = Filter; + //This->Stream->lpVtbl->SetFormat(This->Stream, (PKSDATAFORMAT)This->Format); DPRINT1("Setting state to acquire %x\n", This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_ACQUIRE)); DPRINT1("Setting state to pause %x\n", This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_PAUSE)); This->State = KSSTATE_PAUSE;
+ //This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, This->Delay);
return STATUS_SUCCESS; }
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c [iso-8859-1] Sun Aug 2 20:20:39 2009 @@ -124,7 +124,6 @@ IPortTopology* iface) { IPortTopologyImpl * This = (IPortTopologyImpl*)iface; - return InterlockedIncrement(&This->ref); }
@@ -136,6 +135,7 @@ IPortTopologyImpl * This = (IPortTopologyImpl*)iface;
InterlockedDecrement(&This->ref); + DPRINT("Reference Count %u\n", This->ref);
if (This->ref == 0) { @@ -208,9 +208,7 @@ This->pDeviceObject = DeviceObject; This->bInitialized = TRUE;
- /* increment reference on miniport adapter */ - Miniport->lpVtbl->AddRef(Miniport); - + /* now initialize the miniport driver */ Status = Miniport->lpVtbl->Init(Miniport, UnknownAdapter, ResourceList, iface); if (!NT_SUCCESS(Status)) { @@ -394,10 +392,17 @@ ISubDevice_fnReleaseChildren( IN ISubdevice *iface) { - //IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblSubDevice); - - UNIMPLEMENTED - return STATUS_UNSUCCESSFUL; + IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblSubDevice); + + DPRINT1("ISubDevice_fnReleaseChildren with ref %u\n", This->ref); + + /* release the filter */ + This->Filter->lpVtbl->Release(This->Filter); + + /* release the miniport */ + DPRINT("Refs %u %u\n", This->pMiniport->lpVtbl->Release(This->pMiniport), This->ref); + + return STATUS_SUCCESS; }
static
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c [iso-8859-1] Sun Aug 2 20:20:39 2009 @@ -266,12 +266,6 @@
if (This->ref == 0) { - if (This->pPinCount) - This->pPinCount->lpVtbl->Release(This->pPinCount); - - if (This->pPowerNotify) - This->pPowerNotify->lpVtbl->Release(This->pPowerNotify); - FreeItem(This, TAG_PORTCLASS); return 0; } @@ -342,9 +336,6 @@ This->pDeviceObject = DeviceObject; This->bInitialized = TRUE; This->pResourceList = ResourceList; - - /* increment reference on miniport adapter */ - Miniport->lpVtbl->AddRef(Miniport);
Status = Miniport->lpVtbl->Init(Miniport, UnknownAdapter, ResourceList, iface); if (!NT_SUCCESS(Status)) @@ -644,10 +635,29 @@ ISubDevice_fnReleaseChildren( IN ISubdevice *iface) { - //IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice); - - UNIMPLEMENTED - return STATUS_UNSUCCESSFUL; + IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice); + + DPRINT("ISubDevice_fnReleaseChildren ref %u\n", This->ref); + + /* release the filter */ + This->Filter->lpVtbl->Release(This->Filter); + + if (This->pPinCount) + { + /* release pincount interface */ + This->pPinCount->lpVtbl->Release(This->pPinCount); + } + + if (This->pPowerNotify) + { + /* release power notify interface */ + This->pPowerNotify->lpVtbl->Release(This->pPowerNotify); + } + + /* now release the miniport */ + This->pMiniport->lpVtbl->Release(This->pMiniport); + + return STATUS_SUCCESS; }
static
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/main.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/main.c [iso-8859-1] Sun Aug 2 20:20:39 2009 @@ -47,8 +47,17 @@ DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry);
DPRINT1("Freeing item %wZ\n", &DeviceEntry->DeviceName); + + /* dereference audio device file object */ + ObDereferenceObject(DeviceEntry->FileObject); + + /* close audio device handle */ + ZwClose(DeviceEntry->Handle); + /* free device string */ RtlFreeUnicodeString(&DeviceEntry->DeviceName); - + /* free pins */ + ExFreePool(DeviceEntry->Pins); + /* free audio device entry */ ExFreePool(DeviceEntry); }