mirror of
https://github.com/reactos/reactos.git
synced 2025-05-06 18:31:26 +00:00
[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:
parent
93109445ba
commit
2d8cd02bb5
7 changed files with 125 additions and 103 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue