[PORTCLS]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Sun, 2 Aug 2009 18:20:39 +0000 (18:20 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Sun, 2 Aug 2009 18:20:39 +0000 (18:20 +0000)
- 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

reactos/drivers/wdm/audio/backpln/portcls/filter_topology.c
reactos/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.c
reactos/drivers/wdm/audio/backpln/portcls/irp.c
reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c
reactos/drivers/wdm/audio/backpln/portcls/port_topology.c
reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c
reactos/drivers/wdm/audio/sysaudio/main.c

index 8f6bade..c2b3492 100644 (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);
+
+        /* 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);
 
@@ -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;
 
index 4abf7ca..7790373 100644 (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;
 }
index d731e25..a2111cb 100644 (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;
index 1f919b0..86162cf 100644 (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;
 }
index 58cb6e6..c98a818 100644 (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
index eef0193..80df401 100644 (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
index 6cdf252..d1134c8 100644 (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);
     }