- Implement enumerating sysaudio devices using device interface or using static symbo...
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Fri, 20 Feb 2009 17:52:47 +0000 (17:52 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Fri, 20 Feb 2009 17:52:47 +0000 (17:52 +0000)
- Implement a few options of sysaudio property set
- Implement an object dispatcher like in portcls which will be used to forward requests

svn path=/trunk/; revision=39694

12 files changed:
reactos/drivers/wdm/audio/legacy/wdmaud/control.c [new file with mode: 0644]
reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c [new file with mode: 0644]
reactos/drivers/wdm/audio/legacy/wdmaud/entry.c
reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h
reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild
reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rc [new file with mode: 0644]
reactos/drivers/wdm/audio/sysaudio/control.c [new file with mode: 0644]
reactos/drivers/wdm/audio/sysaudio/deviface.c [new file with mode: 0644]
reactos/drivers/wdm/audio/sysaudio/dispatcher.c [new file with mode: 0644]
reactos/drivers/wdm/audio/sysaudio/main.c
reactos/drivers/wdm/audio/sysaudio/sysaudio.h
reactos/drivers/wdm/audio/sysaudio/sysaudio.rbuild

diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
new file mode 100644 (file)
index 0000000..f6dcfd3
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS Kernel Streaming
+ * FILE:            drivers/wdm/audio/legacy/wdmaud/deviface.c
+ * PURPOSE:         System Audio graph builder
+ * PROGRAMMER:      Andrew Greenwood
+ *                  Johannes Anderwald
+ */
+#include "wdmaud.h"
+
+
+NTSTATUS
+NTAPI
+WdmAudDeviceControl(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  PIRP Irp)
+{
+    PIO_STACK_LOCATION IoStack;
+
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(WDMAUD_DEVICE_INFO))
+    {
+        Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+        Irp->IoStatus.Information = 0;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    DPRINT1("WdmAudDeviceControl entered\n");
+
+    switch(IoStack->Parameters.DeviceIoControl.IoControlCode)
+    {
+        case IOCTL_OPEN_WDMAUD:
+            //return WdmAudDeviceControlOpen(DeviceObject, Irp);
+        case IOCTL_CLOSE_WDMAUD:
+        case IOCTL_GETNUMDEVS_TYPE:
+        case IOCTL_SETDEVICE_STATE:
+        case IOCTL_GETDEVID:
+        case IOCTL_GETVOLUME:
+        case IOCTL_SETVOLUME:
+        case IOCTL_GETCAPABILITIES:
+        case IOCTL_WRITEDATA:
+           break;
+    }
+
+
+
+
+    UNIMPLEMENTED
+
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    Irp->IoStatus.Information = 0;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    return STATUS_SUCCESS;
+}
diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c b/reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c
new file mode 100644 (file)
index 0000000..8b0f556
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS Kernel Streaming
+ * FILE:            drivers/wdm/audio/legacy/wdmaud/deviface.c
+ * PURPOSE:         System Audio graph builder
+ * PROGRAMMER:      Andrew Greenwood
+ *                  Johannes Anderwald
+ */
+#include "wdmaud.h"
+
+NTSTATUS
+WdmAudOpenSysAudioDevice(
+    IN LPWSTR DeviceName,
+    OUT PHANDLE Handle)
+{
+    UNICODE_STRING SymbolicLink;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    IO_STATUS_BLOCK IoStatusBlock;
+    NTSTATUS Status;
+
+    RtlInitUnicodeString(&SymbolicLink, DeviceName);
+    InitializeObjectAttributes(&ObjectAttributes, &SymbolicLink, OBJ_OPENIF | OBJ_KERNEL_HANDLE, NULL, NULL);
+
+    Status = IoCreateFile(Handle,
+                          SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE,
+                          &ObjectAttributes,
+                          &IoStatusBlock,
+                          NULL,
+                          0,
+                          0,
+                          FILE_OPEN,
+                          FILE_SYNCHRONOUS_IO_NONALERT,
+                          NULL,
+                          0,
+                          CreateFileTypeNone,
+                          NULL,
+                          IO_NO_PARAMETER_CHECKING | IO_FORCE_ACCESS_CHECK);
+
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+DeviceInterfaceChangeCallback(
+    IN PVOID NotificationStructure,
+    IN PVOID Context)
+{
+    DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)NotificationStructure;
+
+    DPRINT1("DeviceInterfaceChangeCallback called %p\n", Event);
+    DbgBreakPoint();
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+WdmAudOpenSysAudioDeviceInterfaces(
+    IN PWDMAUD_DEVICE_EXTENSION DeviceExtension,
+    IN LPWSTR SymbolicLinkList)
+{
+    SYSAUDIO_ENTRY * Entry;
+    ULONG Length;
+
+    DPRINT1("WdmAudOpenSysAudioDeviceInterfaces called\n");
+
+    while(*SymbolicLinkList)
+    {
+        Length = wcslen(SymbolicLinkList) + 1;
+        Entry = (SYSAUDIO_ENTRY*)ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_ENTRY) + Length * sizeof(WCHAR));
+        if (!Entry)
+        {
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        Entry->SymbolicLink.Length = Length * sizeof(WCHAR);
+        Entry->SymbolicLink.MaximumLength = Length * sizeof(WCHAR);
+        Entry->SymbolicLink.Buffer = (LPWSTR) (Entry + 1);
+        wcscpy(Entry->SymbolicLink.Buffer, SymbolicLinkList);
+
+        InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry);
+
+        DeviceExtension->NumSysAudioDevices++;
+        SymbolicLinkList += Length;
+    }
+    return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+WdmAudOpenSysAudioDevices(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PWDMAUD_DEVICE_EXTENSION DeviceExtension)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    LPWSTR SymbolicLinkList;
+    SYSAUDIO_ENTRY * Entry;
+    ULONG Length;
+    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\sysaudio");
+
+    if (DeviceExtension->DeviceInterfaceSupport)
+    {
+        Status = IoGetDeviceInterfaces(&KSCATEGORY_SYSAUDIO,
+                                       NULL,
+                                       0,
+                                       &SymbolicLinkList);
+
+        if (NT_SUCCESS(Status))
+        {
+            WdmAudOpenSysAudioDeviceInterfaces(DeviceExtension, SymbolicLinkList);
+            ExFreePool(SymbolicLinkList);
+        }
+
+
+        Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
+                                                PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
+                                               (PVOID)&KSCATEGORY_SYSAUDIO,
+                                                DeviceObject->DriverObject,
+                                                DeviceInterfaceChangeCallback,
+                                               (PVOID)DeviceExtension,
+                                               &DeviceExtension->SysAudioNotification);
+    }
+    else
+    {
+            Length = wcslen(DeviceName.Buffer) + 1;
+            Entry = (SYSAUDIO_ENTRY*)ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_ENTRY) + Length * sizeof(WCHAR));
+            if (!Entry)
+            {
+                return STATUS_INSUFFICIENT_RESOURCES;
+            }
+
+            Entry->SymbolicLink.Length = Entry->SymbolicLink.MaximumLength = Length * sizeof(WCHAR);
+            Entry->SymbolicLink.MaximumLength += sizeof(WCHAR);
+            Entry->SymbolicLink.Buffer = (LPWSTR) (Entry + 1);
+
+            wcscpy(Entry->SymbolicLink.Buffer, DeviceName.Buffer);
+
+            InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry);
+            DeviceExtension->NumSysAudioDevices++;
+    }
+    return Status;
+}
+
+NTSTATUS
+WdmAudRegisterDeviceInterface(
+    IN PDEVICE_OBJECT PhysicalDeviceObject,
+    IN PWDMAUD_DEVICE_EXTENSION DeviceExtension)
+{
+    NTSTATUS Status;
+    UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\wdmaud");
+    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\wdmaud");
+    UNICODE_STRING SymbolicLinkName;
+
+    Status = IoRegisterDeviceInterface(PhysicalDeviceObject, &KSCATEGORY_WDMAUD, NULL, &SymbolicLinkName);
+    if (NT_SUCCESS(Status))
+    {
+        IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
+        RtlFreeUnicodeString(&SymbolicLinkName);
+        DeviceExtension->DeviceInterfaceSupport = TRUE;
+        return Status;
+    }
+
+    /* failed to register device interface
+     * create a symbolic link instead 
+     */
+    DeviceExtension->DeviceInterfaceSupport = FALSE;
+
+    Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
+    if (!NT_SUCCESS(Status))
+    {
+        IoDeleteDevice(PhysicalDeviceObject); //FIXME
+        DPRINT("Failed to create wdmaud symlink!\n");
+        return Status;
+    }
+
+    return Status;
+}
+
+NTSTATUS
+WdmAudOpenSysaudio(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PWDMAUD_CLIENT *pClient)
+{
+    PWDMAUD_CLIENT Client;
+    NTSTATUS Status;
+    HANDLE hSysAudio;
+    PSYSAUDIO_ENTRY SysEntry;
+    PFILE_OBJECT FileObject;
+    PWDMAUD_DEVICE_EXTENSION DeviceExtension;
+
+    DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+    if (!DeviceExtension->NumSysAudioDevices)
+        return STATUS_UNSUCCESSFUL;
+
+    ASSERT(!IsListEmpty(&DeviceExtension->SysAudioDeviceList));
+
+    Client = ExAllocatePool(NonPagedPool, sizeof(WDMAUD_CLIENT));
+    if (!Client)
+    {
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    RtlZeroMemory(Client, sizeof(WDMAUD_CLIENT));
+
+
+    /* open the first sysaudio device available */
+    SysEntry = (PSYSAUDIO_ENTRY)DeviceExtension->SysAudioDeviceList.Flink;
+
+    DPRINT1("Opening device %S\n", SysEntry->SymbolicLink.Buffer);
+    Status = WdmAudOpenSysAudioDevice(SysEntry->SymbolicLink.Buffer, &hSysAudio);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to open sysaudio %x\n", Status);
+        ExFreePool(Client);
+        return Status;
+    }
+
+    /* get the file object */
+    Status = ObReferenceObjectByHandle(hSysAudio, FILE_READ_DATA | FILE_WRITE_DATA, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to reference FileObject %x\n", Status);
+        ExFreePool(Client);
+        ZwClose(hSysAudio);
+        return Status;
+    }
+
+    Client->hSysAudio = hSysAudio;
+    Client->FileObject = FileObject;
+    Client->hProcess = PsGetCurrentProcessId();
+
+    *pClient = Client;
+
+    return STATUS_SUCCESS;
+}
+
+
+
index 4c6c7c2..dbb432e 100644 (file)
@@ -9,23 +9,24 @@
 #include "wdmaud.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}};
 
 NTSTATUS
 NTAPI
-WdmAudAddDevice(
-    IN  PDRIVER_OBJECT  DriverObject,
-    IN  PDEVICE_OBJECT  PhysicalDeviceObject)
+WdmAudInstallDevice(
+    IN  PDRIVER_OBJECT  DriverObject)
 {
+    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\wdmaud");
+    UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\wdmaud");
     PDEVICE_OBJECT DeviceObject;
-    PDEVICE_OBJECT NextDeviceObject;
     NTSTATUS Status;
     PWDMAUD_DEVICE_EXTENSION DeviceExtension;
 
-    DPRINT("WdmAudAddDevice called\n");
+    DPRINT1("WdmAudInstallDevice called\n");
 
     Status = IoCreateDevice(DriverObject,
                             sizeof(WDMAUD_DEVICE_EXTENSION),
-                            NULL,
+                            &DeviceName,
                             FILE_DEVICE_KS,
                             0,
                             FALSE,
@@ -37,27 +38,44 @@ WdmAudAddDevice(
         return Status;
     }
 
+    /* clear device extension */
     DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
     RtlZeroMemory(DeviceExtension, sizeof(WDMAUD_DEVICE_EXTENSION));
 
+    /* register device interfaces */
+    Status = WdmAudRegisterDeviceInterface(DeviceObject, DeviceExtension);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("WdmRegisterDeviceInterface failed with %x\n", Status);
+        IoDeleteDevice(DeviceObject);
+        return Status;
+    }
+
+    /* initialize sysaudio device list */
     InitializeListHead(&DeviceExtension->SysAudioDeviceList);
 
-    Status = KsAllocateDeviceHeader(&DeviceExtension->DeviceHeader, 0, NULL);
+    /* initialize spinlock */
+    KeInitializeSpinLock(&DeviceExtension->Lock);
+
+    /* find available sysaudio devices */
+    Status = WdmAudOpenSysAudioDevices(DeviceObject, DeviceExtension);
     if (!NT_SUCCESS(Status))
     {
-        DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status);
+        DPRINT1("WdmAudOpenSysAudioDevices failed with %x\n", Status);
+        IoDeleteSymbolicLink(&SymlinkName);
         IoDeleteDevice(DeviceObject);
         return Status;
     }
-
-    NextDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
-    if (NextDeviceObject)
+    /* allocate ks device header */
+    Status = KsAllocateDeviceHeader(&DeviceExtension->DeviceHeader, 0, NULL);
+    if (!NT_SUCCESS(Status))
     {
-        /// FIXME
-        /// KsSetDevicePnpAndBaseObject((KSDEVICE_HEADER)DeviceObject->DeviceExtension, NextDeviceObject, DeviceObject);
+        DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status);
+        IoDeleteSymbolicLink(&SymlinkName);
+        IoDeleteDevice(DeviceObject);
+        return Status;
     }
 
-
     DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
     DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
 
@@ -69,7 +87,7 @@ NTAPI
 WdmAudUnload(
     IN PDRIVER_OBJECT driver)
 {
-    DPRINT("WdmAudUnload called\n");
+    DPRINT1("WdmAudUnload called\n");
 }
 
 NTSTATUS
@@ -80,7 +98,7 @@ WdmAudPnp(
 {
     PIO_STACK_LOCATION IrpStack;
 
-    DPRINT("WdmAudPnp called\n");
+    DPRINT1("WdmAudPnp called\n");
 
     IrpStack = IoGetCurrentIrpStackLocation(Irp);
 
@@ -92,115 +110,6 @@ WdmAudPnp(
     return KsDefaultDispatchPnp(DeviceObject, Irp);
 }
 
-NTSTATUS
-WdmAudOpenSysAudioDevice(
-    IN LPWSTR DeviceName,
-    OUT PHANDLE Handle)
-{
-    UNICODE_STRING SymbolicLink;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    IO_STATUS_BLOCK IoStatusBlock;
-    NTSTATUS Status;
-
-    RtlInitUnicodeString(&SymbolicLink, DeviceName);
-    InitializeObjectAttributes(&ObjectAttributes, &SymbolicLink, OBJ_OPENIF | OBJ_KERNEL_HANDLE, NULL, NULL);
-
-    Status = IoCreateFile(Handle,
-                          SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE,
-                          &ObjectAttributes,
-                          &IoStatusBlock,
-                          NULL,
-                          0,
-                          0,
-                          FILE_OPEN,
-                          FILE_SYNCHRONOUS_IO_NONALERT,
-                          NULL,
-                          0,
-                          CreateFileTypeNone,
-                          NULL,
-                          IO_NO_PARAMETER_CHECKING | IO_FORCE_ACCESS_CHECK);
-
-    return Status;
-}
-
-NTSTATUS
-NTAPI
-DeviceInterfaceChangeCallback(
-    IN PVOID NotificationStructure,
-    IN PVOID Context)
-{
-    DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)NotificationStructure;
-
-    DPRINT1("DeviceInterfaceChangeCallback called %p\n", Event);
-    return STATUS_SUCCESS;
-}
-
-NTSTATUS
-WdmAudOpenSysAudioDeviceInterfaces(
-    IN PWDMAUD_DEVICE_EXTENSION DeviceExtension,
-    IN LPWSTR SymbolicLinkList)
-{
-    NTSTATUS Status;
-    HANDLE Handle;
-    SYSAUDIO_ENTRY * Entry;
-    UINT Length;
-    PFILE_OBJECT FileObject;
-    ULONG Result;
-    ULONG BytesReturned;
-    KSPROPERTY KsPropset = {{STATIC_KSPROPSETID_Sysaudio}, KSPROPERTY_SYSAUDIO_DEVICE_DEFAULT, KSPROPERTY_TYPE_SET};
-
-    while(*SymbolicLinkList)
-    {
-        Length = wcslen(SymbolicLinkList) + 1;
-        Status = WdmAudOpenSysAudioDevice(SymbolicLinkList, &Handle);
-        if (NT_SUCCESS(Status))
-        {
-            Status = ObReferenceObjectByHandle(Handle, 
-                                               FILE_READ_DATA | FILE_WRITE_DATA,
-                                               IoFileObjectType,
-                                               KernelMode,
-                                               (PVOID*)&FileObject,
-                                               NULL);
-
-            if (!NT_SUCCESS(Status))
-            {
-                DPRINT1("ObReferenceObjectByHandle failed with %x\n", Status);
-                ZwClose(Handle);
-            }
-
-            Entry = (SYSAUDIO_ENTRY*)ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_ENTRY) + Length * sizeof(WCHAR));
-            if (!Entry)
-            {
-                ZwClose(Handle);
-                ObDereferenceObject((PVOID)FileObject);
-                return STATUS_INSUFFICIENT_RESOURCES;
-            }
-
-            Entry->Handle = Handle;
-            Entry->SymbolicLink.Length = Length * sizeof(WCHAR);
-            Entry->SymbolicLink.MaximumLength = Length * sizeof(WCHAR);
-            Entry->SymbolicLink.Buffer = (LPWSTR) (Entry + 1);
-            Entry->FileObject = FileObject;
-            wcscpy(Entry->SymbolicLink.Buffer, SymbolicLinkList);
-
-            InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry);
-
-            /* set device as default device */
-            KsSynchronousIoControlDevice(FileObject, 
-                                         KernelMode,
-                                         IOCTL_KS_PROPERTY,
-                                         (PVOID)&KsPropset, 
-                                         sizeof(KSPROPERTY),
-                                         (PVOID)&Result,
-                                         sizeof(ULONG),
-                                         &BytesReturned);
-
-            DeviceExtension->NumSysAudioDevices++;
-        }
-        SymbolicLinkList += Length;
-    }
-    return STATUS_SUCCESS;
-}
 
 NTSTATUS
 NTAPI
@@ -209,15 +118,17 @@ WdmAudCreate(
     IN  PIRP Irp)
 {
     NTSTATUS Status;
-    LPWSTR SymbolicLinkList;
+
+    PIO_STACK_LOCATION IoStack;
+    WDMAUD_CLIENT *pClient;
+
     PWDMAUD_DEVICE_EXTENSION DeviceExtension;
 
     DPRINT1("WdmAudCreate\n");
 
-
     DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
-#if 0
+#if KS_IMPLEMENTED
     Status = KsReferenceSoftwareBusObject((KSDEVICE_HEADER)DeviceObject->DeviceExtension);
     if (!NT_SUCCESS(Status))
     {
@@ -226,26 +137,20 @@ WdmAudCreate(
     }
 #endif
 
-    Status = IoGetDeviceInterfaces(&KSCATEGORY_SYSAUDIO,
-                                   NULL,
-                                   0,
-                                   &SymbolicLinkList);
-
-    if (NT_SUCCESS(Status))
+    Status = WdmAudOpenSysaudio(DeviceObject, &pClient);
+    if (!NT_SUCCESS(Status))
     {
-        WdmAudOpenSysAudioDeviceInterfaces(DeviceExtension, SymbolicLinkList);
-        ExFreePool(SymbolicLinkList);
+        DPRINT1("Failed to open sysaudio!\n");
+        if (pClient)
+            ExFreePool(pClient);
     }
 
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+    ASSERT(IoStack->FileObject);
 
-    Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
-                                            PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
-                                            (PVOID)&KSCATEGORY_SYSAUDIO,
-                                            DeviceObject->DriverObject,
-                                            DeviceInterfaceChangeCallback,
-                                            (PVOID)DeviceExtension,
-                                            &DeviceExtension->SysAudioNotification);
-
+    /* store client context in file object */
+    IoStack->FileObject->FsContext = pClient;
+    Status = STATUS_SUCCESS;
 
     Irp->IoStatus.Status = Status;
     Irp->IoStatus.Information = 0;
@@ -262,40 +167,39 @@ WdmAudClose(
 {
     NTSTATUS Status = STATUS_SUCCESS;
     PWDMAUD_DEVICE_EXTENSION DeviceExtension;
+    PIO_STACK_LOCATION IoStack;
+    WDMAUD_CLIENT *pClient;
 
     DPRINT1("WdmAudClose\n");
 
     DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
-#if 0
+#if KS_IMPLEMENTED
     Status = KsDereferenceSoftwareBusObject(DeviceExtension->DeviceHeader);
-#endif
 
     if (NT_SUCCESS(Status))
     {
-        Status = IoUnregisterPlugPlayNotification(DeviceExtension->SysAudioNotification);
+        if (DeviceExtension->SysAudioNotification)
+            Status = IoUnregisterPlugPlayNotification(DeviceExtension->SysAudioNotification);
     }
+#endif
 
-    Irp->IoStatus.Status = Status;
-    Irp->IoStatus.Information = 0;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
 
-    return Status;
-}
+    pClient = (WDMAUD_CLIENT*)IoStack->FileObject->FsContext;
+    if (pClient)
+    {
+        ZwClose(pClient->hSysAudio);
+        ExFreePool(pClient);
+        IoStack->FileObject->FsContext = NULL;
+    }
 
-NTSTATUS
-NTAPI
-WdmAudDeviceControl(
-    IN  PDEVICE_OBJECT DeviceObject,
-    IN  PIRP Irp)
-{
-    UNIMPLEMENTED
 
-    Irp->IoStatus.Status = STATUS_SUCCESS;
+    Irp->IoStatus.Status = Status;
     Irp->IoStatus.Information = 0;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-    return STATUS_SUCCESS;
+    return Status;
 }
 
 NTSTATUS
@@ -321,9 +225,8 @@ DriverEntry(
     IN PUNICODE_STRING Registry_path
 )
 {
-    DPRINT("Wdmaud.sys loaded\n");
+    DPRINT1("Wdmaud.sys loaded\n");
 
-    Driver->DriverExtension->AddDevice = WdmAudAddDevice;
     Driver->DriverUnload = WdmAudUnload;
 
 
@@ -335,6 +238,5 @@ DriverEntry(
     Driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = WdmAudDeviceControl;
     Driver->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower;
 
-
-    return STATUS_SUCCESS;
+    return WdmAudInstallDevice(Driver);
 }
index 62e2f39..7fc6ba6 100644 (file)
@@ -57,28 +57,54 @@ typedef struct
 } WAVEINCAPS; 
 #endif
 
+#include "interface.h"
 
+typedef struct
+{
+    HANDLE hProcess;
+    HANDLE hSysAudio;
+    PFILE_OBJECT FileObject;
 
-#include "interface.h"
+}WDMAUD_CLIENT, *PWDMAUD_CLIENT;
 
 typedef struct
 {
     LIST_ENTRY Entry;
-    HANDLE Handle;
     UNICODE_STRING SymbolicLink;
-    PFILE_OBJECT FileObject;
-}SYSAUDIO_ENTRY;
+}SYSAUDIO_ENTRY, *PSYSAUDIO_ENTRY;
 
 typedef struct
 {
     KSDEVICE_HEADER DeviceHeader;
     PVOID SysAudioNotification;
 
+    BOOL DeviceInterfaceSupport;
+
+    KSPIN_LOCK Lock;
     ULONG NumSysAudioDevices;
     LIST_ENTRY SysAudioDeviceList;
 
 }WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION;
 
-
+NTSTATUS
+WdmAudRegisterDeviceInterface(
+    IN PDEVICE_OBJECT PhysicalDeviceObject,
+    IN PWDMAUD_DEVICE_EXTENSION DeviceExtension);
+
+NTSTATUS
+WdmAudOpenSysAudioDevices(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PWDMAUD_DEVICE_EXTENSION DeviceExtension);
+
+NTSTATUS
+WdmAudOpenSysaudio(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PWDMAUD_CLIENT *pClient);
+
+NTSTATUS
+NTAPI
+WdmAudDeviceControl(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  PIRP Irp);
 
 #endif
index 93ab5bb..1656885 100644 (file)
@@ -2,8 +2,12 @@
 <!DOCTYPE module SYSTEM "../../../../../tools/rbuild/project.dtd">
 <module name="wdmaud_kernel" type="kernelmodedriver" installbase="system32/drivers" installname="wdmaud.sys">
        <include base="wdmaud_kernel">.</include>
+       <define name="_COMDDK_" />
        <include base="ReactOS">include/reactos/libs/sound</include>
        <library>ntoskrnl</library>
        <library>ks</library>
+       <file>control.c</file>
+       <file>deviface.c</file>
        <file>entry.c</file>
+       <file>wdmaud.rc</file>
 </module>
diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rc b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rc
new file mode 100644 (file)
index 0000000..84a27f7
--- /dev/null
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION   "Reactos audio mapper driver\0"
+#define REACTOS_STR_INTERNAL_NAME      "wdmaud\0"
+#define REACTOS_STR_ORIGINAL_FILENAME  "wdmaud.sys\0"
+#include <reactos/version.rc>
diff --git a/reactos/drivers/wdm/audio/sysaudio/control.c b/reactos/drivers/wdm/audio/sysaudio/control.c
new file mode 100644 (file)
index 0000000..d885cb2
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS Kernel Streaming
+ * FILE:            drivers/wdm/audio/sysaudio/control.c
+ * PURPOSE:         System Audio graph builder
+ * PROGRAMMER:      Johannes Anderwald
+ */
+
+#include <ntifs.h>
+#include <ntddk.h>
+#include <portcls.h>
+#include <ks.h>
+#include <ksmedia.h>
+#include <math.h>
+#define YDEBUG
+#include <debug.h>
+#include "sysaudio.h"
+
+const GUID KSPROPSETID_Sysaudio                 = {0xCBE3FAA0L, 0xCC75, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}};
+const GUID KSPROPSETID_Sysaudio_Pin             = {0xA3A53220L, 0xC6E4, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}};
+const GUID KSPROPSETID_General                  = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
+
+
+NTSTATUS
+SetIrpIoStatus(
+    IN PIRP Irp,
+    IN NTSTATUS Status,
+    IN ULONG Length)
+{
+    Irp->IoStatus.Information = Length;
+    Irp->IoStatus.Status = Status;
+    return Status;
+
+}
+
+PKSAUDIO_DEVICE_ENTRY
+GetListEntry(
+    IN PLIST_ENTRY Head,
+    IN ULONG Index)
+{
+    PLIST_ENTRY Entry = Head->Flink;
+
+    while(Index-- && Entry != Head)
+        Entry = Entry->Flink;
+
+    if (Entry == Head)
+        return NULL;
+
+    return (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry);
+}
+
+NTSTATUS
+SysAudioOpenVirtualDevice(
+    IN PIRP Irp,
+    IN ULONG DeviceNumber,
+    PSYSAUDIODEVEXT DeviceExtension)
+{
+    PULONG Index;
+    ULONG Count;
+    PSYSAUDIO_CLIENT ClientInfo;
+    PKSAUDIO_DEVICE_ENTRY Entry;
+    PKSOBJECT_CREATE_ITEM CreateItem;
+
+    /* access the create item */
+    CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
+    ASSERT(CreateItem);
+
+    if (DeviceNumber >= DeviceExtension->NumberOfKsAudioDevices)
+    {
+        /* invalid device index */
+        return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
+    }
+
+    /* get device context */
+    Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, DeviceNumber);
+    ASSERT(Entry != NULL);
+
+    /* get client context */
+    ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context;
+    /* does the client already use a device */
+    if (!ClientInfo->NumDevices)
+    {
+        /* first device to be openend */
+        ClientInfo->Devices = ExAllocatePool(NonPagedPool, sizeof(ULONG));
+        if (!ClientInfo->Devices)
+        {
+            /* no memory */
+            return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+        }
+        ClientInfo->NumDevices = 1;
+        ClientInfo->Devices[0] = DeviceNumber;
+        /* increase usage count */
+        Entry->NumberOfClients++;
+        return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
+    }
+
+    /* check if device has already been openend */
+    for(Count = 0; Count < ClientInfo->NumDevices; Count++)
+    {
+        if (ClientInfo->Devices[Count] == DeviceNumber)
+        {
+            /* device has already been opened */
+            return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
+        }
+    }
+    /* new device to be openend */
+    Index = ExAllocatePool(NonPagedPool, sizeof(ULONG) * (ClientInfo->NumDevices + 1));
+    if (!Index)
+    {
+        /* no memory */
+        return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+    }
+    /* increase usage count */
+    Entry->NumberOfClients++;
+
+    /* copy device count array */
+    RtlMoveMemory(Index, ClientInfo->Devices, ClientInfo->NumDevices * sizeof(ULONG));
+    Index[ClientInfo->NumDevices] = DeviceNumber;
+    ExFreePool(ClientInfo->Devices);
+    ClientInfo->NumDevices++;
+    ClientInfo->Devices = Index;
+
+    return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
+
+}
+
+
+NTSTATUS
+SysAudioHandleProperty(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
+{
+    PIO_STACK_LOCATION IoStack;
+    NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
+    KSPROPERTY PropertyRequest;
+    KSCOMPONENTID ComponentId;
+    PULONG Index;
+    PKSPROPERTY Property;
+    PSYSAUDIODEVEXT DeviceExtension;
+    PKSAUDIO_DEVICE_ENTRY Entry;
+    PSYSAUDIO_INSTANCE_INFO InstanceInfo;
+    PSYSAUDIO_CLIENT ClientInfo;
+    ULONG Count, BytesReturned;
+    PKSOBJECT_CREATE_ITEM CreateItem;
+    UNICODE_STRING GuidString;
+
+    /* access the create item */
+    CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
+
+
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY))
+    {
+        /* buffer must be atleast of sizeof KSPROPERTY */
+        return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPROPERTY));
+    }
+
+    Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+    DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
+
+    if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Sysaudio))
+    {
+        if (Property->Id == KSPROPERTY_SYSAUDIO_COMPONENT_ID)
+        {
+            if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY) + sizeof(ULONG))
+            {
+                /* too small buffer */
+                return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSPROPERTY) + sizeof(ULONG));
+            }
+
+            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSCOMPONENTID))
+            {
+                /* too small buffer */
+                return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSCOMPONENTID));
+            }
+
+            Index = (PULONG)(Property + 1);
+
+            if (DeviceExtension->NumberOfKsAudioDevices <= *Index)
+            {
+                /* invalid index */
+                return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
+            }
+            Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, *Index);
+            ASSERT(Entry != NULL);
+
+            PropertyRequest.Set = KSPROPSETID_General;
+            PropertyRequest.Id = KSPROPERTY_GENERAL_COMPONENTID;
+            PropertyRequest.Flags = KSPROPERTY_TYPE_GET;
+
+            /* call the filter */
+            Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_WRITE_STREAM, (PVOID)&PropertyRequest, sizeof(KSPROPERTY), (PVOID)&ComponentId, sizeof(KSCOMPONENTID), &BytesReturned);
+            if (!NT_SUCCESS(Status))
+            {
+                DPRINT1("KsSynchronousIoControlDevice failed with %x for KSPROPERTY_GENERAL_COMPONENTID\n", Status);
+                return SetIrpIoStatus(Irp, Status, 0);
+            }
+            RtlMoveMemory(Irp->UserBuffer, &ComponentId, sizeof(KSCOMPONENTID));
+            return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(KSCOMPONENTID));
+        }
+        else if (Property->Id == KSPROPERTY_SYSAUDIO_DEVICE_COUNT)
+        {
+            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
+            {
+                /* too small buffer */
+                return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(ULONG));
+            }
+            *((PULONG)Irp->UserBuffer) = DeviceExtension->NumberOfKsAudioDevices;
+            return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(ULONG));
+        }
+        else if (Property->Id == KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE)
+        {
+            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
+            {
+                /* too small buffer */
+                return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSCOMPONENTID));
+            }
+
+            if (Property->Flags & KSPROPERTY_TYPE_SET)
+            {
+                Index = (PULONG)Irp->UserBuffer;
+                return SysAudioOpenVirtualDevice(Irp, *Index, DeviceExtension);
+            }
+            else if (Property->Flags & KSPROPERTY_TYPE_GET)
+            {
+                Index = (PULONG)Irp->UserBuffer;
+                /* get client context */
+                ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context;
+                ASSERT(ClientInfo);
+                /* does the client already use a device */
+                if (!ClientInfo->NumDevices)
+                {
+                    /* no device open */
+                    return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+                }
+                /* store last opened device number */
+                *Index = ClientInfo->Devices[ClientInfo->NumDevices-1];
+                /* found no device with that device index open */
+                return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(ULONG));
+            }
+        }
+        else if (Property->Id == KSPROPERTY_SYSAUDIO_INSTANCE_INFO)
+        {
+            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SYSAUDIO_INSTANCE_INFO))
+            {
+                /* too small buffer */
+                return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(SYSAUDIO_INSTANCE_INFO));
+            }
+
+            /* get input parameter */
+            InstanceInfo = (PSYSAUDIO_INSTANCE_INFO)Property;
+
+            if (Property->Flags & KSPROPERTY_TYPE_SET)
+            {
+                return SysAudioOpenVirtualDevice(Irp, InstanceInfo->DeviceNumber, DeviceExtension);
+            }
+            else if (Property->Flags & KSPROPERTY_TYPE_GET)
+            {
+                /* get client context */
+                ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context;
+                ASSERT(ClientInfo);
+                /* does the client already use a device */
+                if (!ClientInfo->NumDevices)
+                {
+                    /* no device open */
+                    return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+                }
+                for(Count = 0; Count < ClientInfo->NumDevices; Count++)
+                {
+                    if (ClientInfo->Devices[Count] == InstanceInfo->DeviceNumber)
+                    {
+                        /* specified device is open */
+                        return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
+                    }
+                }
+                /* found no device with that device index open */
+                return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+            }
+        }
+    }
+
+    RtlStringFromGUID(&Property->Set, &GuidString);
+    DPRINT1("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
+    DbgBreakPoint();
+    RtlFreeUnicodeString(&GuidString);
+
+    return Status;
+}
+
+
diff --git a/reactos/drivers/wdm/audio/sysaudio/deviface.c b/reactos/drivers/wdm/audio/sysaudio/deviface.c
new file mode 100644 (file)
index 0000000..32d71c4
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS Kernel Streaming
+ * FILE:            drivers/wdm/audio/sysaudio/deviface.c
+ * PURPOSE:         System Audio graph builder
+ * PROGRAMMER:      Johannes Anderwald
+ */
+
+#include <ntifs.h>
+#include <ntddk.h>
+#include <portcls.h>
+#include <ks.h>
+#include <ksmedia.h>
+#include <math.h>
+#define YDEBUG
+#include <debug.h>
+#include "sysaudio.h"
+
+const GUID GUID_DEVICE_INTERFACE_ARRIVAL       = {0xCB3A4004L, 0x46F0, 0x11D0, {0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F}};
+const GUID GUID_DEVICE_INTERFACE_REMOVAL       = {0xCB3A4005L, 0x46F0, 0x11D0, {0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F}};
+const GUID KS_CATEGORY_AUDIO                   = {0x6994AD04L, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
+const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL    = {0xBF963D80L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}};
+
+
+NTSTATUS
+NTAPI
+DeviceInterfaceChangeCallback(
+    IN PVOID NotificationStructure,
+    IN PVOID Context)
+{
+    DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event;
+    SYSAUDIODEVEXT *DeviceExtension = (SYSAUDIODEVEXT*)Context;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    Event = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)NotificationStructure;
+
+    if (IsEqualGUIDAligned(&Event->Event,
+                           &GUID_DEVICE_INTERFACE_ARRIVAL))
+    {
+        /* a new device has arrived */
+
+        PFILE_OBJECT FileObject = NULL;
+        PKSAUDIO_DEVICE_ENTRY DeviceEntry;
+        HANDLE NodeHandle;
+        IO_STATUS_BLOCK IoStatusBlock;
+        OBJECT_ATTRIBUTES ObjectAttributes;
+
+
+        DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY));
+        if (!DeviceEntry)
+        {
+            DPRINT1("No Mem\n");
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+        DeviceEntry->DeviceName.Length = 0;
+        DeviceEntry->DeviceName.MaximumLength = Event->SymbolicLinkName->Length + 5 * sizeof(WCHAR);
+        DeviceEntry->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceEntry->DeviceName.MaximumLength);
+        if (!DeviceEntry->DeviceName.Buffer)
+        {
+            DPRINT1("No Mem\n");
+            ExFreePool(DeviceEntry);
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        if (!NT_SUCCESS(RtlAppendUnicodeToString(&DeviceEntry->DeviceName, L"\\??\\")))
+        {
+            DPRINT1("No Mem\n");
+            ExFreePool(DeviceEntry->DeviceName.Buffer);
+            ExFreePool(DeviceEntry);
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&DeviceEntry->DeviceName, Event->SymbolicLinkName)))
+        {
+            DPRINT1("No Mem\n");
+            ExFreePool(DeviceEntry->DeviceName.Buffer);
+            ExFreePool(DeviceEntry);
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        DPRINT1("Sym %wZ\n", &DeviceEntry->DeviceName);
+
+        InitializeObjectAttributes(&ObjectAttributes, &DeviceEntry->DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
+
+        Status = ZwCreateFile(&NodeHandle,
+                              GENERIC_READ | GENERIC_WRITE,
+                              &ObjectAttributes,
+                              &IoStatusBlock,
+                              NULL,
+                              0,
+                              0,
+                              FILE_OPEN,
+                              FILE_SYNCHRONOUS_IO_NONALERT,
+                              NULL,
+                              0);
+
+
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("ZwCreateFile failed with %x\n", Status);
+            ExFreePool(DeviceEntry);
+            return Status;
+        }
+
+        Status = ObReferenceObjectByHandle(NodeHandle, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+        if (!NT_SUCCESS(Status))
+        {
+            ZwClose(NodeHandle);
+            ExFreePool(DeviceEntry);
+            DPRINT1("ObReferenceObjectByHandle failed with %x\n", Status);
+            return Status;
+        }
+
+        DeviceEntry->Handle = NodeHandle;
+        DeviceEntry->FileObject = FileObject;
+
+        InsertTailList(&DeviceExtension->KsAudioDeviceList, &DeviceEntry->Entry);
+        DeviceExtension->NumberOfKsAudioDevices++;
+
+        DPRINT1("Successfully opened audio device handle %p file object %p device object %p\n", NodeHandle, FileObject, FileObject->DeviceObject);
+        return Status;
+    }
+    else if (IsEqualGUIDAligned(&Event->Event,
+                                &GUID_DEVICE_INTERFACE_REMOVAL))
+    {
+        DPRINT1("Remove interface to audio device!\n");
+        ///FIXME
+        ///
+        return STATUS_SUCCESS;
+    }
+    else
+    {
+        UNICODE_STRING EventName, InterfaceGuid;
+
+        RtlStringFromGUID(&Event->Event, &EventName);
+        RtlStringFromGUID(&Event->InterfaceClassGuid, &InterfaceGuid);
+        DPRINT1("Unknown event: Event %wZ GUID %wZ\n", &EventName, &InterfaceGuid);
+        return STATUS_SUCCESS;
+    }
+
+}
+
+NTSTATUS
+SysAudioRegisterNotifications(
+    IN  PDRIVER_OBJECT  DriverObject,
+    SYSAUDIODEVEXT *DeviceExtension)
+{
+    NTSTATUS Status;
+
+
+    Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
+                                            PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
+                                            (PVOID)&KS_CATEGORY_AUDIO,
+                                            DriverObject,
+                                            DeviceInterfaceChangeCallback,
+                                            (PVOID)DeviceExtension,
+                                            (PVOID*)&DeviceExtension->KsAudioNotificationEntry);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("IoRegisterPlugPlayNotification failed with %x\n", Status);
+        return Status;
+    }
+
+    Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
+                                            PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
+                                            (PVOID)&DMOCATEGORY_ACOUSTIC_ECHO_CANCEL,
+                                            DriverObject,
+                                            DeviceInterfaceChangeCallback,
+                                            (PVOID)DeviceExtension,
+                                            (PVOID*)&DeviceExtension->EchoCancelNotificationEntry);
+
+    if (!NT_SUCCESS(Status))
+    {
+        /* ignore failure for now */
+        DPRINT1("IoRegisterPlugPlayNotification failed for DMOCATEGORY_ACOUSTIC_ECHO_CANCEL\n", Status);
+    }
+
+    return STATUS_SUCCESS;
+}
+
+
+
+NTSTATUS
+SysAudioRegisterDeviceInterfaces(
+    IN PDEVICE_OBJECT DeviceObject)
+{
+    NTSTATUS Status;
+    UNICODE_STRING SymbolicLink;
+
+    Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_PREFERRED_MIDIOUT_DEVICE, NULL, &SymbolicLink);
+    if (NT_SUCCESS(Status))
+    {
+        IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
+        RtlFreeUnicodeString(&SymbolicLink);
+    }
+    else
+    {
+        DPRINT1("Failed to register KSCATEGORY_PREFERRED_MIDIOUT_DEVICE interface Status %x\n", Status);
+        return Status;
+    }
+
+    Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_PREFERRED_WAVEIN_DEVICE, NULL, &SymbolicLink);
+    if (NT_SUCCESS(Status))
+    {
+        IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
+        RtlFreeUnicodeString(&SymbolicLink);
+    }
+    else
+    {
+        DPRINT1("Failed to register KSCATEGORY_PREFERRED_WAVEIN_DEVICE interface Status %x\n", Status);
+        return Status;
+    }
+
+    Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_PREFERRED_WAVEOUT_DEVICE, NULL, &SymbolicLink);
+    if (NT_SUCCESS(Status))
+    {
+        IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
+        RtlFreeUnicodeString(&SymbolicLink);
+    }
+    else
+    {
+        DPRINT1("Failed to register KSCATEGORY_PREFERRED_WAVEOUT_DEVICE interface Status %x\n", Status);
+    }
+
+    Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_SYSAUDIO, NULL, &SymbolicLink);
+    if (NT_SUCCESS(Status))
+    {
+        IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
+        RtlFreeUnicodeString(&SymbolicLink);
+    }
+    else
+    {
+        DPRINT1("Failed to register KSCATEGORY_SYSAUDIO interface Status %x\n", Status);
+    }
+
+    return Status;
+}
+
diff --git a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c
new file mode 100644 (file)
index 0000000..0def7c9
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS Kernel Streaming
+ * FILE:            drivers/wdm/audio/sysaudio/dispatcher.c
+ * PURPOSE:         System Audio graph builder
+ * PROGRAMMER:      Johannes Anderwald
+ */
+
+#include <ntifs.h>
+#include <ntddk.h>
+#include <portcls.h>
+#include <ks.h>
+#include <ksmedia.h>
+#include <math.h>
+#define YDEBUG
+#include <debug.h>
+#include "sysaudio.h"
+
+NTSTATUS
+NTAPI
+Dispatch_fnDeviceIoControl(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
+{
+    PIO_STACK_LOCATION IoStack;
+
+    DPRINT1("Dispatch_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
+
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+
+    if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
+    {
+       return SysAudioHandleProperty(DeviceObject, Irp);
+    }
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+Dispatch_fnRead(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
+{
+    DPRINT1("Dispatch_fnRead called DeviceObject %p Irp %p\n", DeviceObject);
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+Dispatch_fnWrite(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
+{
+    DPRINT1("Dispatch_fnWrite called DeviceObject %p Irp %p\n", DeviceObject);
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+Dispatch_fnFlush(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
+{
+    DPRINT1("Dispatch_fnFlush called DeviceObject %p Irp %p\n", DeviceObject);
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+Dispatch_fnClose(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
+{
+    DPRINT1("Dispatch_fnClose called DeviceObject %p Irp %p\n", DeviceObject);
+
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+Dispatch_fnQuerySecurity(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
+{
+    DPRINT1("Dispatch_fnQuerySecurity called DeviceObject %p Irp %p\n", DeviceObject);
+
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+Dispatch_fnSetSecurity(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
+{
+
+    DPRINT1("Dispatch_fnSetSecurity called DeviceObject %p Irp %p\n", DeviceObject);
+
+    return STATUS_SUCCESS;
+}
+
+BOOLEAN
+NTAPI
+Dispatch_fnFastDeviceIoControl(
+    PFILE_OBJECT FileObject,
+    BOOLEAN Wait,
+    PVOID InputBuffer,
+    ULONG InputBufferLength,
+    PVOID OutputBuffer,
+    ULONG OutputBufferLength,
+    ULONG IoControlCode,
+    PIO_STATUS_BLOCK IoStatus,
+    PDEVICE_OBJECT DeviceObject)
+{
+    DPRINT1("Dispatch_fnFastDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
+
+
+    return FALSE;
+}
+
+
+BOOLEAN
+NTAPI
+Dispatch_fnFastRead(
+    PFILE_OBJECT FileObject,
+    PLARGE_INTEGER FileOffset,
+    ULONG Length,
+    BOOLEAN Wait,
+    ULONG LockKey,
+    PVOID Buffer,
+    PIO_STATUS_BLOCK IoStatus,
+    PDEVICE_OBJECT DeviceObject)
+{
+    DPRINT1("Dispatch_fnFastRead called DeviceObject %p Irp %p\n", DeviceObject);
+
+    return FALSE;
+
+}
+
+BOOLEAN
+NTAPI
+Dispatch_fnFastWrite(
+    PFILE_OBJECT FileObject,
+    PLARGE_INTEGER FileOffset,
+    ULONG Length,
+    BOOLEAN Wait,
+    ULONG LockKey,
+    PVOID Buffer,
+    PIO_STATUS_BLOCK IoStatus,
+    PDEVICE_OBJECT DeviceObject)
+{
+    DPRINT1("Dispatch_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject);
+
+    return FALSE;
+}
+
+static KSDISPATCH_TABLE DispatchTable =
+{
+    Dispatch_fnDeviceIoControl,
+    Dispatch_fnRead,
+    Dispatch_fnWrite,
+    Dispatch_fnFlush,
+    Dispatch_fnClose,
+    Dispatch_fnQuerySecurity,
+    Dispatch_fnSetSecurity,
+    Dispatch_fnFastDeviceIoControl,
+    Dispatch_fnFastRead,
+    Dispatch_fnFastWrite,
+};
+
+NTSTATUS
+NTAPI
+DispatchCreateSysAudio(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  PIRP Irp)
+{
+    NTSTATUS Status;
+    KSOBJECT_HEADER ObjectHeader;
+    PSYSAUDIO_CLIENT Client;
+    PKSOBJECT_CREATE_ITEM CreateItem;
+
+    DPRINT1("DispatchCreateSysAudio entered\n");
+    DbgBreakPoint();
+
+    /* allocate create item */
+    CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
+    if (!CreateItem)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    Client = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_CLIENT));
+    if (!Client)
+    {
+        ExFreePool(CreateItem);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+    /* initialize client struct */
+    RtlZeroMemory(Client, sizeof(SYSAUDIO_CLIENT));
+
+    /* zero create struct */
+    RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
+
+    /* store create context */
+    CreateItem->Context = (PVOID)Client;
+
+    /* allocate object header */
+    Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);
+
+    DPRINT1("KsAllocateObjectHeader result %x\n", Status);
+    return Status;
+}
+
+NTSTATUS
+SysAudioAllocateDeviceHeader(
+    IN SYSAUDIODEVEXT *DeviceExtension)
+{
+    NTSTATUS Status;
+    PKSOBJECT_CREATE_ITEM CreateItem;
+
+    /* allocate create item */
+    CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
+    if (!CreateItem)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+
+
+    /* initialize create item struct */
+    RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
+    CreateItem->Create = DispatchCreateSysAudio;
+    RtlInitUnicodeString(&CreateItem->ObjectClass, L"SysAudio");
+
+    Status = KsAllocateDeviceHeader(&DeviceExtension->KsDeviceHeader,
+                                    1,
+                                    CreateItem);
+
+    return Status;
+}
+
index e20db49..d17708e 100644 (file)
@@ -4,7 +4,7 @@
  * FILE:            drivers/wdm/audio/sysaudio/main.c
  * PURPOSE:         System Audio graph builder
  * PROGRAMMER:      Andrew Greenwood
- *
+ *                  Johannes Anderwald
  * HISTORY:
  *                  8 Jul 07    Started basic implementation
  */
 #include <ntddk.h>
 #include <portcls.h>
 #include <ks.h>
+#include <ksmedia.h>
+#include <math.h>
 #define YDEBUG
 #include <debug.h>
 //#include <dxsdk/mediaobj.h>
 #include "sysaudio.h"
 
-const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL    = {0xBF963D80L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}};
+
 const GUID KSCATEGORY_SYSAUDIO                 = {0xA7C7A5B1L, 0x5AF3, 0x11D1, {0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07}};
 const GUID KSCATEGORY_AUDIO_DEVICE             = {0xFBF6F530L, 0x07B9, 0x11D2, {0xA7, 0x1E, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
 const GUID KSCATEGORY_PREFERRED_WAVEOUT_DEVICE = {0xD6C5066EL, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
 const GUID KSCATEGORY_PREFERRED_WAVEIN_DEVICE  = {0xD6C50671L, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
 const GUID KSCATEGORY_PREFERRED_MIDIOUT_DEVICE = {0xD6C50674L, 0x72C1, 0x11D2, {0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88}};
-const GUID KS_CATEGORY_AUDIO                   = {0x6994AD04L, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
-const GUID GUID_DEVICE_INTERFACE_ARRIVAL       = {0xCB3A4004L, 0x46F0, 0x11D0, {0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F}};
-const GUID GUID_DEVICE_INTERFACE_REMOVAL       = {0xCB3A4005L, 0x46F0, 0x11D0, {0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F}};
+
 
 
 VOID
@@ -49,13 +49,12 @@ SysAudio_Pnp(
     IrpStack = IoGetCurrentIrpStackLocation(Irp);
 
     DPRINT1("SysAudio_Pnp called for func %x\n", IrpStack->MinorFunction);
-       DbgBreakPoint();
 
     DeviceExtension = (SYSAUDIODEVEXT*)DeviceObject->DeviceExtension;
 
 
     if (IrpStack->MinorFunction == IRP_MN_START_DEVICE)
-       {
+    {
     DPRINT1("SysAudio_Pnp called for func IRP_MN_START_DEVICE\n");
     Irp->IoStatus.Status = STATUS_SUCCESS;
     Irp->IoStatus.Information = 0;
@@ -81,132 +80,6 @@ SysAudio_Pnp(
     return KsDefaultDispatchPnp(DeviceObject, Irp);
 }
 
-NTSTATUS
-NTAPI
-DeviceInterfaceChangeCallback(
-    IN PVOID NotificationStructure,
-    IN PVOID Context)
-{
-    DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event;
-    SYSAUDIODEVEXT *DeviceExtension = (SYSAUDIODEVEXT*)Context;
-    NTSTATUS Status = STATUS_SUCCESS;
-
-    Event = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)NotificationStructure;
-
-    if (IsEqualGUIDAligned(&Event->Event,
-                           &GUID_DEVICE_INTERFACE_ARRIVAL))
-    {
-        /* a new device has arrived */
-
-        PFILE_OBJECT FileObject = NULL;
-        PKSAUDIO_DEVICE_ENTRY DeviceEntry;
-        HANDLE NodeHandle;
-        IO_STATUS_BLOCK IoStatusBlock;
-        OBJECT_ATTRIBUTES ObjectAttributes;
-
-        DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY));
-        if (!DeviceEntry)
-            return STATUS_INSUFFICIENT_RESOURCES;
-
-        DeviceEntry->DeviceName.Length = 0;
-        DeviceEntry->DeviceName.MaximumLength = Event->SymbolicLinkName->Length + 5 * sizeof(WCHAR);
-        DeviceEntry->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceEntry->DeviceName.MaximumLength);
-        if (!DeviceEntry->DeviceName.Buffer)
-        {
-            ExFreePool(DeviceEntry);
-            return STATUS_INSUFFICIENT_RESOURCES;
-        }
-
-        if (!NT_SUCCESS(RtlAppendUnicodeToString(&DeviceEntry->DeviceName, L"\\??\\")))
-        {
-
-            ExFreePool(DeviceEntry->DeviceName.Buffer);
-            ExFreePool(DeviceEntry);
-            return STATUS_INSUFFICIENT_RESOURCES;
-        }
-
-        if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&DeviceEntry->DeviceName, Event->SymbolicLinkName)))
-        {
-
-            ExFreePool(DeviceEntry->DeviceName.Buffer);
-            ExFreePool(DeviceEntry);
-            return STATUS_INSUFFICIENT_RESOURCES;
-        }
-
-        DPRINT1("Sym %wZ\n", &DeviceEntry->DeviceName);
-
-        InitializeObjectAttributes(&ObjectAttributes, &DeviceEntry->DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
-
-        Status = ZwCreateFile(&NodeHandle,
-                              GENERIC_READ | GENERIC_WRITE,
-                              &ObjectAttributes,
-                              &IoStatusBlock,
-                              NULL,
-                              0,
-                              0,
-                              FILE_OPEN,
-                              FILE_SYNCHRONOUS_IO_NONALERT,
-                              NULL,
-                              0);
-
-
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT1("ZwCreateFile failed with %x\n", Status);
-            ExFreePool(DeviceEntry);
-            return Status;
-        }
-
-        Status = ObReferenceObjectByHandle(NodeHandle, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
-        if (!NT_SUCCESS(Status))
-        {
-            ZwClose(NodeHandle);
-            ExFreePool(DeviceEntry);
-            DPRINT1("ObReferenceObjectByHandle failed with %x\n", Status);
-            return Status;
-        }
-
-        DeviceEntry->Handle = NodeHandle;
-        DeviceEntry->FileObject = FileObject;
-
-        InsertTailList(&DeviceExtension->KsAudioDeviceList, &DeviceEntry->Entry);
-        DeviceExtension->NumberOfKsAudioDevices++;
-
-        DPRINT1("Successfully opened audio device handle %p file object %p device object %p\n", NodeHandle, FileObject, FileObject->DeviceObject);
-        return Status;
-    }
-    else if (IsEqualGUIDAligned(&Event->Event,
-                                &GUID_DEVICE_INTERFACE_REMOVAL))
-    {
-        DPRINT1("Remove interface to audio device!\n");
-        ///FIXME
-        ///
-        return STATUS_SUCCESS;
-    }
-    else
-    {
-        UNICODE_STRING EventName, InterfaceGuid;
-
-        RtlStringFromGUID(&Event->Event, &EventName);
-        RtlStringFromGUID(&Event->InterfaceClassGuid, &InterfaceGuid);
-        DPRINT1("Unknown event: Event %wZ GUID %wZ\n", &EventName, &InterfaceGuid);
-        return STATUS_SUCCESS;
-    }
-
-
-}
-
-NTSTATUS
-NTAPI
-DispatchCreate(
-    IN  PDEVICE_OBJECT DeviceObject,
-    IN  PIRP Irp)
-{
-    DPRINT1("DispatchCreate\n");
-
-    return STATUS_SUCCESS;
-}
-
 NTSTATUS
 NTAPI
 SysAudio_InstallDevice(
@@ -217,9 +90,8 @@ SysAudio_InstallDevice(
     UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\sysaudio");
     PDEVICE_OBJECT DeviceObject;
     //PDEVICE_OBJECT NextDeviceObject;
-    KSOBJECT_CREATE_ITEM CreateItem;
     SYSAUDIODEVEXT *DeviceExtension;
-    UNICODE_STRING SymbolicLink;
+
 
     DPRINT1("SysAudio_InstallDevice called\n");
 
@@ -239,16 +111,22 @@ SysAudio_InstallDevice(
         return Status;
     }
 
-    /* create the symbolic link */
-    Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
+    /* register device interfaces */
+    Status = SysAudioRegisterDeviceInterfaces(DeviceObject);
     if (!NT_SUCCESS(Status))
     {
-        IoDeleteDevice(DeviceObject);
-        DPRINT("Failed to create \\DosDevices\\sysaudio symlink!\n");
-        return Status;
+        /* failed to register
+         * create a hack interface
+         */
+        Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
+        if (!NT_SUCCESS(Status))
+        {
+            IoDeleteDevice(DeviceObject);
+            DPRINT("Failed to create sysaudio symlink!\n");
+            return Status;
+        }
     }
 
-
     DeviceExtension = (SYSAUDIODEVEXT*)DeviceObject->DeviceExtension;
     /* initialize device extension */
     RtlZeroMemory(DeviceExtension, sizeof(SYSAUDIODEVEXT));
@@ -257,109 +135,27 @@ SysAudio_InstallDevice(
     //DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
     InitializeListHead(&DeviceExtension->KsAudioDeviceList);
 
-    /* initialize create item struct */
-    RtlZeroMemory(&CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
-    CreateItem.Create = DispatchCreate;
-
-    Status = KsAllocateDeviceHeader(&DeviceExtension->KsDeviceHeader,
-                                    1,
-                                    &CreateItem);
-
+    Status = SysAudioAllocateDeviceHeader(DeviceExtension);
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status);
         goto cleanup;
     }
 
-#if 0
-    //NextDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
-    /// FIXME
-    /// KsSetDevicePnpAndBaseObject(DeviceExtension->KsDeviceHeader, NextDeviceObject, DeviceObject);
-    ///
-    /// DeviceExtension->NextDeviceObject = NextDeviceObject;
-#endif
-
-    Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
-                                            PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
-                                            (PVOID)&KS_CATEGORY_AUDIO,
-                                            DriverObject,
-                                            DeviceInterfaceChangeCallback,
-                                            (PVOID)DeviceExtension,
-                                            (PVOID*)&DeviceExtension->KsAudioNotificationEntry);
-
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("IoRegisterPlugPlayNotification failed with %x\n", Status);
-        goto cleanup;
-    }
-
-#if 0
-    Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
-                                            PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
-                                            (PVOID)&DMOCATEGORY_ACOUSTIC_ECHO_CANCEL,
-                                            DriverObject,
-                                            DeviceInterfaceChangeCallback,
-                                            (PVOID)DeviceExtension,
-                                            (PVOID*)&DeviceExtension->EchoCancelNotificationEntry);
-
+    Status = SysAudioRegisterNotifications(DriverObject,
+                                         DeviceExtension);
     if (!NT_SUCCESS(Status))
     {
-        DPRINT1("IoRegisterPlugPlayNotification failed with %x\n", Status);
+        DPRINT1("Failed to register device notifications\n");
         goto cleanup;
     }
-#endif
-
-     Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_PREFERRED_MIDIOUT_DEVICE, NULL, &SymbolicLink);
-     if (NT_SUCCESS(Status))
-     {
-         IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
-         RtlFreeUnicodeString(&SymbolicLink);
-     }
-     else
-     {
-         DPRINT1("Failed to register KSCATEGORY_PREFERRED_MIDIOUT_DEVICE interface Status %x\n", Status);
-     }
-
-     Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_PREFERRED_WAVEIN_DEVICE, NULL, &SymbolicLink);
-     if (NT_SUCCESS(Status))
-     {
-         IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
-         RtlFreeUnicodeString(&SymbolicLink);
-     }
-     else
-     {
-         DPRINT1("Failed to register KSCATEGORY_PREFERRED_WAVEIN_DEVICE interface Status %x\n", Status);
-     }
-
-     Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_PREFERRED_WAVEOUT_DEVICE, NULL, &SymbolicLink);
-     if (NT_SUCCESS(Status))
-     {
-         IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
-         RtlFreeUnicodeString(&SymbolicLink);
-     }
-     else
-     {
-         DPRINT1("Failed to register KSCATEGORY_PREFERRED_WAVEOUT_DEVICE interface Status %x\n", Status);
-     }
-
-     Status = IoRegisterDeviceInterface(DeviceObject, &KSCATEGORY_SYSAUDIO, NULL, &SymbolicLink);
-     if (NT_SUCCESS(Status))
-     {
-         IoSetDeviceInterfaceState(&SymbolicLink, TRUE);
-         RtlFreeUnicodeString(&SymbolicLink);
-     }
-     else
-     {
-         DPRINT1("Failed to register KSCATEGORY_SYSAUDIO interface Status %x\n", Status);
-     }
-
 
      /* set io flags */
      DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
      /* clear initializing flag */
      DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
 
-    DPRINT("Device SysAudio_AddDevice result %x\n", Status);
+    DPRINT("Device SysAudio_InstallDevice result %x\n", Status);
     return STATUS_SUCCESS;
 
 cleanup:
@@ -375,23 +171,6 @@ cleanup:
     return Status;
 }
 
-NTSTATUS
-NTAPI
-SysAudio_Stub(
-    IN  PDEVICE_OBJECT DeviceObject,
-    IN  PIRP Irp)
-{
-    DPRINT1("SysAudio_Stub called\n");
-
-    /* TODO */
-
-       Irp->IoStatus.Status = STATUS_SUCCESS;
-    Irp->IoStatus.Information = 0;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return STATUS_SUCCESS;
-}
-
 NTSTATUS NTAPI
 DriverEntry(
     IN  PDRIVER_OBJECT DriverObject,
@@ -399,20 +178,10 @@ DriverEntry(
 {
     DPRINT1("System audio graph builder (sysaudio) started\n");
 
-    DPRINT1("Setting KS function handlers\n");
-
-#if KS_IMPLEMENTED
     KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CREATE);
     KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE);
     KsSetMajorFunctionHandler(DriverObject, IRP_MJ_WRITE);
     KsSetMajorFunctionHandler(DriverObject, IRP_MJ_DEVICE_CONTROL);
-#else
-    DriverObject->MajorFunction[IRP_MJ_CREATE] = SysAudio_Stub;
-    DriverObject->MajorFunction[IRP_MJ_CLOSE] = SysAudio_Stub;
-    DriverObject->MajorFunction[IRP_MJ_WRITE] = SysAudio_Stub;
-    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SysAudio_Stub;
-#endif
-
 
     DriverObject->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower;
     DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = KsDefaultForwardIrp;
index 5136591..a766e8e 100644 (file)
@@ -1,6 +1,14 @@
 #ifndef SYSAUDIO_H__
 #define SYSAUDIO_H__
 
+typedef struct
+{
+    ULONG NumDevices;
+    PULONG Devices;
+
+}SYSAUDIO_CLIENT, *PSYSAUDIO_CLIENT;
+
+
 typedef struct
 {
     LIST_ENTRY Entry;
@@ -8,6 +16,7 @@ typedef struct
     PFILE_OBJECT FileObject;
     UNICODE_STRING DeviceName;
 
+    ULONG NumberOfClients;
 }KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY;
 
 
@@ -17,10 +26,29 @@ typedef struct
     PDEVICE_OBJECT NextDeviceObject;
     KSDEVICE_HEADER KsDeviceHeader;
     ULONG NumberOfKsAudioDevices;
+
     LIST_ENTRY KsAudioDeviceList;
     PVOID KsAudioNotificationEntry;
     PVOID EchoCancelNotificationEntry;
     KMUTEX Mutex;
-}SYSAUDIODEVEXT;
+}SYSAUDIODEVEXT, *PSYSAUDIODEVEXT;
+
+NTSTATUS
+SysAudioAllocateDeviceHeader(
+    IN SYSAUDIODEVEXT *DeviceExtension);
+
+NTSTATUS
+SysAudioRegisterDeviceInterfaces(
+    IN PDEVICE_OBJECT DeviceObject);
+
+NTSTATUS
+SysAudioRegisterNotifications(
+    IN  PDRIVER_OBJECT  DriverObject,
+    SYSAUDIODEVEXT *DeviceExtension);
+
+NTSTATUS
+SysAudioHandleProperty(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp);
 
 #endif
index 0e27735..44655a4 100644 (file)
@@ -4,7 +4,11 @@
        <include base="sysaudio">.</include>
        <library>ntoskrnl</library>
        <library>ks</library>
+       <library>libcntpr</library>
        <define name="_COMDDK_" />
+       <file>control.c</file>
+       <file>deviface.c</file>
+       <file>dispatcher.c</file>
        <file>main.c</file>
        <file>sysaudio.rc</file>
 </module>