[WDMAUD] Close mixers on cleanup. Should fix CORE-10735 definitely (#21)
[reactos.git] / drivers / wdm / audio / legacy / wdmaud / mmixer.c
index ce8b6fa..3016d24 100644 (file)
@@ -8,6 +8,10 @@
 
 #include "wdmaud.h"
 
+#include <mmixer.h>
+
+#define NDEBUG
+#include <debug.h>
 
 PVOID Alloc(ULONG NumBytes);
 MIXER_STATUS Close(HANDLE hDevice);
@@ -198,7 +202,7 @@ Control(
     PFILE_OBJECT FileObject;
 
     /* get file object */
-    Status = ObReferenceObjectByHandle(hMixer, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+    Status = ObReferenceObjectByHandle(hMixer, GENERIC_READ | GENERIC_WRITE, *IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
     if (!NT_SUCCESS(Status))
     {
         DPRINT("failed to reference %p with %lx\n", hMixer, Status);
@@ -262,11 +266,17 @@ Enum(
         return MM_STATUS_UNSUCCESSFUL;
     }
 
-    /* intialize key name */
+    /* initialize key name */
     RtlInitUnicodeString(&KeyName, *DeviceName);
 
     /* open device interface key */
     Status = IoOpenDeviceInterfaceRegistryKey(&KeyName, GENERIC_READ | GENERIC_WRITE, OutKey);
+
+    if (!NT_SUCCESS(Status))
+    {
+        *OutKey = NULL;
+    }
+
 #if 0
     if (!NT_SUCCESS(Status))
     {
@@ -416,7 +426,7 @@ WdmAudControlOpenMixer(
 
     if (DeviceInfo->u.hNotifyEvent)
     {
-        Status = ObReferenceObjectByHandle(DeviceInfo->u.hNotifyEvent, EVENT_MODIFY_STATE, ExEventObjectType, UserMode, (LPVOID*)&EventObject, NULL);
+        Status = ObReferenceObjectByHandle(DeviceInfo->u.hNotifyEvent, EVENT_MODIFY_STATE, *ExEventObjectType, UserMode, (LPVOID*)&EventObject, NULL);
 
         if (!NT_SUCCESS(Status))
         {
@@ -461,6 +471,60 @@ WdmAudControlOpenMixer(
     return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
 }
 
+NTSTATUS
+WdmAudControlCloseMixer(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  PIRP Irp,
+    IN  PWDMAUD_DEVICE_INFO DeviceInfo,
+    IN  PWDMAUD_CLIENT ClientInfo,
+    IN  ULONG Index)
+{
+    /* Remove event associated to this client */
+    if (MMixerClose(&MixerContext, DeviceInfo->DeviceIndex, ClientInfo, EventCallback) != MM_STATUS_SUCCESS)
+    {
+        DPRINT1("Failed to close mixer\n");
+        return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO));
+    }
+
+    /* Dereference event */
+    if (ClientInfo->hPins[Index].NotifyEvent)
+    {
+        ObDereferenceObject(ClientInfo->hPins[Index].NotifyEvent);
+        ClientInfo->hPins[Index].NotifyEvent = NULL;
+    }
+
+    /* FIXME: do we need to free ClientInfo->hPins ? */
+    return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
+}
+
+VOID
+WdmAudCloseAllMixers(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PWDMAUD_CLIENT ClientInfo,
+    IN ULONG Index)
+{
+    ULONG DeviceCount, DeviceIndex;
+
+    /* Get all mixers */
+    DeviceCount = GetSysAudioDeviceCount(DeviceObject);
+
+    /* Close every mixer attached to the device */
+    for (DeviceIndex = 0; DeviceIndex < DeviceCount; DeviceIndex++)
+    {
+        if (MMixerClose(&MixerContext, DeviceIndex, ClientInfo, EventCallback) != MM_STATUS_SUCCESS)
+        {
+            DPRINT1("Failed to close mixer for device %lu\n", DeviceIndex);
+        }
+    }
+    
+    /* Dereference event */
+    if (ClientInfo->hPins[Index].NotifyEvent)
+    {
+        ObDereferenceObject(ClientInfo->hPins[Index].NotifyEvent);
+        ClientInfo->hPins[Index].NotifyEvent = NULL;
+    }
+}
+
 NTSTATUS
 NTAPI
 WdmAudGetControlDetails(
@@ -800,4 +864,3 @@ WdmAudControlOpenMidi(
     else
         return SetIrpIoStatus(Irp, STATUS_NOT_SUPPORTED, sizeof(WDMAUD_DEVICE_INFO));
 }
-