[WDMAUD] Close mixers on cleanup. Should fix CORE-10735 definitely (#21)
[reactos.git] / drivers / wdm / audio / legacy / wdmaud / entry.c
index 5ec4373..eede791 100644 (file)
@@ -6,8 +6,12 @@
  * PROGRAMMER:      Andrew Greenwood
  *                  Johannes Anderwald
  */
+
 #include "wdmaud.h"
 
+#define NDEBUG
+#include <debug.h>
+
 const GUID KSCATEGORY_SYSAUDIO = {0xA7C7A5B1L, 0x5AF3, 0x11D1, {0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07}};
 const GUID KSCATEGORY_WDMAUD   = {0x3E227E76L, 0x690D, 0x11D2, {0x81, 0x61, 0x00, 0x00, 0xF8, 0x77, 0x5B, 0xF1}};
 
@@ -27,6 +31,19 @@ WdmAudInitWorkerRoutine(
     /* get device extension */
     DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
+
+    if (DeviceExtension->FileObject == NULL)
+    {
+        /* find available sysaudio devices */
+        Status = WdmAudOpenSysAudioDevices(DeviceObject, DeviceExtension);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("WdmAudOpenSysAudioDevices failed with %x\n", Status);
+            return;
+        }
+    }
+
+
     /* get device count */
     DeviceCount = GetSysAudioDeviceCount(DeviceObject);
 
@@ -70,20 +87,19 @@ WdmAudTimerRoutine(
 
 NTSTATUS
 NTAPI
-WdmAudInstallDevice(
-    IN  PDRIVER_OBJECT  DriverObject)
+WdmaudAddDevice(
+    IN PDRIVER_OBJECT DriverObject,
+    IN PDEVICE_OBJECT PhysicalDeviceObject)
 {
-    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\wdmaud");
-    UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\wdmaud");
     PDEVICE_OBJECT DeviceObject;
     NTSTATUS Status;
     PWDMAUD_DEVICE_EXTENSION DeviceExtension;
 
-    DPRINT("WdmAudInstallDevice called\n");
+    DPRINT("WdmaudAddDevice called\n");
 
     Status = IoCreateDevice(DriverObject,
                             sizeof(WDMAUD_DEVICE_EXTENSION),
-                            &DeviceName,
+                            NULL,
                             FILE_DEVICE_KS,
                             0,
                             FALSE,
@@ -109,7 +125,7 @@ WdmAudInstallDevice(
     }
 
     /* register device interfaces */
-    Status = WdmAudRegisterDeviceInterface(DeviceObject, DeviceExtension);
+    Status = WdmAudRegisterDeviceInterface(PhysicalDeviceObject, DeviceExtension);
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("WdmRegisterDeviceInterface failed with %x\n", Status);
@@ -132,26 +148,20 @@ WdmAudInstallDevice(
     /* initialize timer */
     IoInitializeTimer(DeviceObject, WdmAudTimerRoutine, (PVOID)WdmAudTimerRoutine);
 
-    /* find available sysaudio devices */
-    Status = WdmAudOpenSysAudioDevices(DeviceObject, DeviceExtension);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("WdmAudOpenSysAudioDevices failed with %x\n", Status);
-        IoDeleteSymbolicLink(&SymlinkName);
-        IoDeleteDevice(DeviceObject);
-        return Status;
-    }
-
     /* allocate ks device header */
     Status = KsAllocateDeviceHeader(&DeviceExtension->DeviceHeader, 0, NULL);
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status);
-        IoDeleteSymbolicLink(&SymlinkName);
         IoDeleteDevice(DeviceObject);
         return Status;
     }
 
+    /* attach to device stack */
+    DeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
+    KsSetDevicePnpAndBaseObject(DeviceExtension->DeviceHeader, DeviceExtension->NextDeviceObject, DeviceObject);
+
+
     /* start the timer */
     IoStartTimer(DeviceObject);
 
@@ -199,10 +209,10 @@ WdmAudCreate(
     NTSTATUS Status;
     PIO_STACK_LOCATION IoStack;
     PWDMAUD_CLIENT pClient;
-    //PWDMAUD_DEVICE_EXTENSION DeviceExtension;
+    PWDMAUD_DEVICE_EXTENSION DeviceExtension;
 
     /* get device extension */
-    //DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
 #if KS_IMPLEMENTED
     Status = KsReferenceSoftwareBusObject((KSDEVICE_HEADER)DeviceObject->DeviceExtension);
@@ -213,6 +223,13 @@ WdmAudCreate(
     }
 #endif
 
+    if (DeviceExtension->FileObject == NULL)
+    {
+        /* initialize */
+        WdmAudInitWorkerRoutine(DeviceObject, NULL);
+    }
+
+
     Status = WdmAudOpenSysaudio(DeviceObject, &pClient);
     if (!NT_SUCCESS(Status))
     {
@@ -309,6 +326,7 @@ WdmAudCleanup(
            /* found an still open audio pin */
            ZwClose(pClient->hPins[Index].Handle);
        }
+       WdmAudCloseAllMixers(DeviceObject, pClient, Index);
     }
 
     /* free pin array */
@@ -350,6 +368,7 @@ DriverEntry(
     Driver->MajorFunction[IRP_MJ_WRITE] = WdmAudReadWrite;
     Driver->MajorFunction[IRP_MJ_READ] = WdmAudReadWrite;
     Driver->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower;
+    Driver->DriverExtension->AddDevice = WdmaudAddDevice;
 
-    return WdmAudInstallDevice(Driver);
+    return STATUS_SUCCESS;
 }