[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


svn path=/trunk/; revision=42344
This commit is contained in:
Johannes Anderwald 2009-08-02 18:20:39 +00:00
parent 93109445ba
commit 2d8cd02bb5
7 changed files with 125 additions and 103 deletions

View file

@ -16,6 +16,7 @@ typedef struct
IPortTopology* Port;
SUBDEVICE_DESCRIPTOR * Descriptor;
ISubdevice *SubDevice;
}IPortFilterTopologyImpl;
@ -112,24 +113,12 @@ IPortFilterTopology_fnDeviceIoControl(
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 @@ IPortFilterTopology_fnClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
//PMINIPORTTOPOLOGY Miniport;
//IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl *)iface;
NTSTATUS Status = STATUS_SUCCESS;
IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl *)iface;
/* release reference to port */
//This->Port->lpVtbl->Release(This->Port);
/* FIXME handle DirectSound */
/* get the miniport driver */
//Miniport = GetTopologyMiniport(This->Port);
/* release miniport driver */
//Miniport->lpVtbl->Release(Miniport);
if (This->ref == 1)
{
/* release reference to port */
This->SubDevice->lpVtbl->Release(This->SubDevice);
Irp->IoStatus.Status = STATUS_SUCCESS;
/* 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 @@ IPortFilterTopology_fnFastDeviceIoControl(
{
ULONG Index;
PKSPROPERTY Property;
NTSTATUS Status;
ISubdevice * SubDevice = NULL;
PSUBDEVICE_DESCRIPTOR Descriptor = NULL;
IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface;
Property = (PKSPROPERTY)InputBuffer;
@ -254,28 +243,14 @@ IPortFilterTopology_fnFastDeviceIoControl(
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))
for(Index = 0; Index < This->Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++)
{
SubDevice->lpVtbl->Release(SubDevice);
return FALSE;
}
for(Index = 0; Index < Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++)
{
if (IsEqualGUIDAligned(&Property->Set, Descriptor->FilterPropertySet.Properties[Index].Set))
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,8 +317,8 @@ IPortFilterTopology_fnInit(
/* 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;
@ -351,9 +326,6 @@ IPortFilterTopology_fnInit(
/* save descriptor */
This->Descriptor = Descriptor;
/* increment reference count */
Port->lpVtbl->AddRef(Port);
/* store port object */
This->Port = Port;

View file

@ -17,6 +17,7 @@ typedef struct
IPortWaveCyclic* Port;
IPortPinWaveCyclic ** Pins;
SUBDEVICE_DESCRIPTOR * Descriptor;
ISubdevice * SubDevice;
}IPortFilterWaveCyclicImpl;
@ -161,24 +162,12 @@ IPortFilterWaveCyclic_fnDeviceIoControl(
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 @@ IPortFilterWaveCyclic_fnClose(
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 @@ IPortFilterWaveCyclic_fnClose(
ASSERT(This->Pins[Index] == NULL);
}
/* release reference to port */
//This->Port->lpVtbl->Release(This->Port);
DPRINT("IPortFilterWaveCyclic_fnClose ref %u\n", This->ref);
/* get the miniport driver */
//Miniport = GetWaveCyclicMiniport(This->Port);
/* release miniport driver */
//Miniport->lpVtbl->Release(Miniport);
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_SUCCESS;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
@ -358,18 +349,16 @@ IPortFilterWaveCyclic_fnInit(
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 @@ IPortFilterWaveCyclic_fnInit(
if (!This->Pins)
return STATUS_UNSUCCESSFUL;
/* increment reference count */
Port->lpVtbl->AddRef(Port);
/* store port driver */
This->Port = Port;
return STATUS_SUCCESS;
}

View file

@ -194,10 +194,39 @@ PortClsShutdown(
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;

View file

@ -777,6 +777,12 @@ CloseStreamRoutine(
/* 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 @@ IPortPinWaveCyclic_fnInit(
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 @@ IPortPinWaveCyclic_fnInit(
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;
}

View file

@ -124,7 +124,6 @@ IPortTopology_fnAddRef(
IPortTopology* iface)
{
IPortTopologyImpl * This = (IPortTopologyImpl*)iface;
return InterlockedIncrement(&This->ref);
}
@ -136,6 +135,7 @@ IPortTopology_fnRelease(
IPortTopologyImpl * This = (IPortTopologyImpl*)iface;
InterlockedDecrement(&This->ref);
DPRINT("Reference Count %u\n", This->ref);
if (This->ref == 0)
{
@ -208,9 +208,7 @@ IPortTopology_fnInit(
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 @@ NTAPI
ISubDevice_fnReleaseChildren(
IN ISubdevice *iface)
{
//IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblSubDevice);
IPortTopologyImpl * This = (IPortTopologyImpl*)CONTAINING_RECORD(iface, IPortTopologyImpl, lpVtblSubDevice);
UNIMPLEMENTED
return STATUS_UNSUCCESSFUL;
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

View file

@ -266,12 +266,6 @@ IPortWaveCyclic_fnRelease(
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;
}
@ -343,9 +337,6 @@ IPortWaveCyclic_fnInit(
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 @@ NTAPI
ISubDevice_fnReleaseChildren(
IN ISubdevice *iface)
{
//IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice);
IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice);
UNIMPLEMENTED
return STATUS_UNSUCCESSFUL;
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

View file

@ -47,8 +47,17 @@ SysAudio_Shutdown(
DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry);
DPRINT1("Freeing item %wZ\n", &DeviceEntry->DeviceName);
RtlFreeUnicodeString(&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);
}