From 6a2637c2d032a6c16ff0e75ffd8d531beb470d94 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 29 May 2009 12:40:09 +0000 Subject: [PATCH] - Use a reference name when registering audio subdevices (bug 4566) - Release subdevice interface when it is no longer needed - Fix a memory leak - Audio support is on hold untill bug 4566 is resolved svn path=/trunk/; revision=41195 --- .../wdm/audio/backpln/portcls/adapter.c | 22 ++++++---- .../audio/backpln/portcls/filter_wavecyclic.c | 40 ++++++++++++++++--- .../wdm/audio/backpln/portcls/interfaces.h | 5 +++ .../drivers/wdm/audio/backpln/portcls/irp.c | 24 ++++++++++- .../audio/backpln/portcls/pin_wavecyclic.c | 3 +- .../audio/backpln/portcls/port_wavecyclic.c | 7 +--- .../audio/backpln/portcls/propertyhandler.c | 3 ++ 7 files changed, 84 insertions(+), 20 deletions(-) diff --git a/reactos/drivers/wdm/audio/backpln/portcls/adapter.c b/reactos/drivers/wdm/audio/backpln/portcls/adapter.c index 34a0b7cd304..972fe7f334e 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/adapter.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/adapter.c @@ -54,6 +54,7 @@ PcInitializeAdapterDriver( DriverObject->MajorFunction[IRP_MJ_PNP] = PcDispatchIrp; DriverObject->MajorFunction[IRP_MJ_POWER] = PcDispatchIrp; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = PcDispatchIrp; + DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = PcDispatchIrp; /* The driver-supplied AddDevice */ DriverObject->DriverExtension->AddDevice = AddDevice; @@ -181,6 +182,10 @@ PcAddAdapterDevice( status = STATUS_UNSUCCESSFUL; goto cleanup; } + + /* register shutdown notification */ + IoRegisterShutdownNotification(PhysicalDeviceObject); + return status; cleanup: @@ -223,6 +228,7 @@ PcRegisterSubdevice( UNICODE_STRING SymbolicLinkName; SUBDEVICE_DESCRIPTOR * SubDeviceDescriptor; ULONG Index; + UNICODE_STRING RefName; DPRINT1("PcRegisterSubdevice DeviceObject %p Name %S Unknown %p\n", DeviceObject, Name, Unknown); ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); @@ -272,18 +278,17 @@ PcRegisterSubdevice( return Status; } - /* increment reference count */ - SubDevice->lpVtbl->AddRef(SubDevice); + /* initialize reference string */ + RtlInitUnicodeString(&RefName, Name); for(Index = 0; Index < SubDeviceDescriptor->InterfaceCount; Index++) { - //FIXME - // Use a reference string such as Wave0001 / Topology0001 - // - + /* FIXME + * check if reference string with that name already exists + */ Status = IoRegisterDeviceInterface(DeviceExt->PhysicalDeviceObject, &SubDeviceDescriptor->Interfaces[Index], - NULL, + &RefName, &SymbolicLinkName); if (NT_SUCCESS(Status)) { @@ -292,5 +297,8 @@ PcRegisterSubdevice( } } + /* Release SubDevice reference */ + SubDevice->lpVtbl->Release(SubDevice); + return STATUS_SUCCESS; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c index d7e6fd68336..b3ba90b7540 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c @@ -236,17 +236,21 @@ IPortFilterWaveCyclic_fnClose( IN PIRP Irp) { ULONG Index; + PMINIPORTWAVECYCLIC Miniport; IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl *)iface; for(Index = 0; Index < This->Descriptor->Factory.PinDescriptorCount; Index++) { - if (This->Pins[Index]) - { - This->Pins[Index]->lpVtbl->Close(This->Pins[Index], DeviceObject, NULL); - } - + /* all pins should have been closed by now */ + ASSERT(This->Pins[Index] == NULL); } + /* release reference to port */ + This->Port->lpVtbl->Release(This->Port); + + Miniport = GetWaveCyclicMiniport(This->Port); + Miniport->lpVtbl->Release(Miniport); + Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; @@ -388,6 +392,29 @@ IPortFilterWaveCyclic_fnInit( return STATUS_SUCCESS; } + +static +NTSTATUS +NTAPI +IPortFilterWaveCyclic_fnFreePin( + IN IPortFilterWaveCyclic* iface, + IN struct IPortPinWaveCyclic* Pin) +{ + ULONG Index; + IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl*)iface; + + for(Index = 0; Index < This->Descriptor->Factory.PinDescriptorCount; Index++) + { + if (This->Pins[Index] == Pin) + { + This->Pins[Index]->lpVtbl->Release(This->Pins[Index]); + This->Pins[Index] = NULL; + return STATUS_SUCCESS; + } + } + return STATUS_UNSUCCESSFUL; +} + static IPortFilterWaveCyclicVtbl vt_IPortFilterWaveCyclic = { IPortFilterWaveCyclic_fnQueryInterface, @@ -404,7 +431,8 @@ static IPortFilterWaveCyclicVtbl vt_IPortFilterWaveCyclic = IPortFilterWaveCyclic_fnFastDeviceIoControl, IPortFilterWaveCyclic_fnFastRead, IPortFilterWaveCyclic_fnFastWrite, - IPortFilterWaveCyclic_fnInit + IPortFilterWaveCyclic_fnInit, + IPortFilterWaveCyclic_fnFreePin }; NTSTATUS diff --git a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h index a0f44eae209..fe136322477 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h +++ b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h @@ -532,6 +532,8 @@ typedef IPortPinWaveRT *PPORTPINWAVERT; #undef INTERFACE #define INTERFACE IPortFilterWaveCyclic +struct IPortPinWaveCyclic; + DECLARE_INTERFACE_(IPortFilterWaveCyclic, IIrpTarget) { DEFINE_ABSTRACT_UNKNOWN() @@ -540,6 +542,9 @@ DECLARE_INTERFACE_(IPortFilterWaveCyclic, IIrpTarget) STDMETHOD_(NTSTATUS, Init)(THIS_ IN PPORTWAVECYCLIC Port)PURE; + + STDMETHOD_(NTSTATUS, FreePin)(THIS_ + IN struct IPortPinWaveCyclic* Pin)PURE; }; typedef IPortFilterWaveCyclic *PPORTFILTERWAVECYCLIC; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/irp.c b/reactos/drivers/wdm/audio/backpln/portcls/irp.c index 3a61c56be68..6f8dd451867 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/irp.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/irp.c @@ -151,7 +151,7 @@ PortClsPnp( IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_NOT_SUPPORTED; case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: - DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS Status %x Information %p\n", Irp->IoStatus.Status, Irp->IoStatus.Information); + DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS Status %x Information %p Information2 %p\n", Irp->IoStatus.Status, Irp->IoStatus.Information, IoStack->Parameters.FilterResourceRequirements.IoResourceRequirementList); Status = Irp->IoStatus.Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; @@ -210,6 +210,25 @@ PortClsSysControl( return STATUS_SUCCESS; } +NTSTATUS +NTAPI +PortClsShutdown( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + DPRINT("PortClsShutdown called\n"); + //DbgBreakPoint(); + + /* TODO */ + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + + /* ========================================================================== @@ -253,6 +272,9 @@ PcDispatchIrp( case IRP_MJ_SYSTEM_CONTROL : return PortClsSysControl(DeviceObject, Irp); + case IRP_MJ_SHUTDOWN: + return PortClsShutdown(DeviceObject, Irp); + default: DPRINT1("Unhandled function %x\n", IoStack->MajorFunction); break; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c index 36b7802d6b2..36d7c60e54d 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c @@ -732,6 +732,7 @@ CloseStreamRoutine( { Stream = This->Stream; This->Stream = NULL; + This->Filter->lpVtbl->FreePin(This->Filter, (IPortPinWaveCyclic*)This); DPRINT1("Closing stream at Irql %u\n", KeGetCurrentIrql()); Stream->lpVtbl->Release(Stream); /* this line is never reached */ @@ -1064,7 +1065,7 @@ IPortPinWaveCyclic_fnInit( //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 run %x\n", This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_PAUSE)); + DPRINT1("Setting state to pause %x\n", This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_PAUSE)); This->State = KSSTATE_PAUSE; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c b/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c index 169890761f0..9f1894b404d 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c @@ -242,7 +242,7 @@ IPortWaveCyclic_fnAddRef( IPortWaveCyclic* iface) { IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface; - + DPRINT("IPortWaveCyclic_fnAddRef %u entered\n", This->ref); return InterlockedIncrement(&This->ref); } @@ -254,13 +254,10 @@ IPortWaveCyclic_fnRelease( IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface; InterlockedDecrement(&This->ref); + DPRINT("IPortWaveCyclic_fnRelease %u entered\n", This->ref); if (This->ref == 0) { - if (This->bInitialized) - { - This->pMiniport->lpVtbl->Release(This->pMiniport); - } if (This->pPinCount) This->pPinCount->lpVtbl->Release(This->pPinCount); diff --git a/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c b/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c index 21fd69abf0a..bd002977388 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c @@ -198,6 +198,9 @@ PinPropertyHandler( /* Release reference */ Port->lpVtbl->Release(Port); + /* Release subdevice reference */ + SubDevice->lpVtbl->Release(SubDevice); + return Status; }