[ros-diffs] [janderwald] 39702: - Fix a bug in KsAllocateDeviceHeader which copied the create item to the wrong offset - Set Created status to true when create function is not zero - Partly implement KsStreamIo - Implement IOCTL for opening / setting state and writing wave data - Clear KSAUDIO_DEVICE_ENTRY - Open the pin in a worker context as IoCreateFile must be called at APC_LEVEL < - Add dispatcher object to sysaudio will dispatch the device requests to the real pin - Add a test application to play a wav sound - ReactOS can now play a wave tone

janderwald at svn.reactos.org janderwald at svn.reactos.org
Sat Feb 21 21:18:45 CET 2009


Author: janderwald
Date: Sat Feb 21 23:18:44 2009
New Revision: 39702

URL: http://svn.reactos.org/svn/reactos?rev=39702&view=rev
Log:
- Fix a bug in KsAllocateDeviceHeader which copied the create item to the wrong offset
- Set Created status to true when create function is not zero
- Partly implement KsStreamIo
- Implement IOCTL for opening / setting state and writing wave data
- Clear KSAUDIO_DEVICE_ENTRY
- Open the pin in a worker context as IoCreateFile must be called at APC_LEVEL <
- Add dispatcher object to sysaudio will dispatch the device requests to the real pin
- Add a test application to play a wav sound
- ReactOS can now play a wave tone

Added:
    trunk/reactos/drivers/wdm/audio/backpln/audio_test/   (with props)
    trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c   (with props)
    trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.rbuild   (with props)
    trunk/reactos/drivers/wdm/audio/sysaudio/pin.c   (with props)
Modified:
    trunk/reactos/drivers/ksfilter/ks/irp.c
    trunk/reactos/drivers/wdm/audio/backpln/directory.rbuild
    trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c
    trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
    trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c
    trunk/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h
    trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h
    trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild
    trunk/reactos/drivers/wdm/audio/sysaudio/control.c
    trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c
    trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c
    trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h
    trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.rbuild

Modified: trunk/reactos/drivers/ksfilter/ks/irp.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/irp.c?rev=39702&r1=39701&r2=39702&view=diff
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] Sat Feb 21 23:18:44 2009
@@ -188,7 +188,11 @@
         for(Index = 0; Index < ItemsCount; Index++)
         {
             /* copy provided create items */
-            RtlMoveMemory(&Header->ItemList[Index], &ItemsList[Index], sizeof(KSOBJECT_CREATE_ITEM));
+            RtlMoveMemory(&Header->ItemList[Index].CreateItem, &ItemsList[Index], sizeof(KSOBJECT_CREATE_ITEM));
+            if (ItemsList[Index].Create!= NULL)
+            {
+                Header->ItemList[Index].bCreated = TRUE;
+            }
         }
         Header->MaxItems = ItemsCount;
     }
@@ -716,7 +720,7 @@
     IN  PDEVICE_OBJECT DeviceObject,
     IN  PIRP Irp)
 {
-    PIO_STACK_LOCATION IoStack;
+    //PIO_STACK_LOCATION IoStack;
     PDEVICE_EXTENSION DeviceExtension;
     PKSIDEVICE_HEADER DeviceHeader;
     ULONG Index;
@@ -725,7 +729,7 @@
 
     DPRINT1("KS / CREATE\n");
     /* get current stack location */
-    IoStack = IoGetCurrentIrpStackLocation(Irp);
+    //IoStack = IoGetCurrentIrpStackLocation(Irp);
     /* get device extension */
     DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
     /* get device header */
@@ -856,7 +860,7 @@
     }
     else
     {
-        DPRINT1("Expected Object Header\n");
+        DPRINT1("Expected Object Header %p\n", IoStack->FileObject);
         KeBugCheckEx(0, 0, 0, 0, 0);
         return STATUS_SUCCESS;
     }
@@ -1049,9 +1053,11 @@
 
 
 /*
-    @unimplemented
-*/
-KSDDKAPI NTSTATUS NTAPI
+    @implemented
+*/
+KSDDKAPI
+NTSTATUS
+NTAPI
 KsStreamIo(
     IN  PFILE_OBJECT FileObject,
     IN  PKEVENT Event OPTIONAL,
@@ -1065,8 +1071,52 @@
     IN  ULONG Flags,
     IN  KPROCESSOR_MODE RequestorMode)
 {
-    UNIMPLEMENTED;
-    return STATUS_UNSUCCESSFUL;
+    PIRP Irp;
+    PIO_STACK_LOCATION IoStack;
+    PDEVICE_OBJECT DeviceObject;
+    ULONG Code;
+    NTSTATUS Status;
+    LARGE_INTEGER Offset;
+
+    if (Flags == KSSTREAM_READ)
+        Code = IRP_MJ_READ;
+    else if (Flags == KSSTREAM_WRITE)
+        Code = IRP_MJ_WRITE;
+    else
+        return STATUS_INVALID_PARAMETER;
+
+    DeviceObject = IoGetRelatedDeviceObject(FileObject);
+    if (!DeviceObject)
+        return STATUS_INVALID_PARAMETER;
+
+    if (Event)
+    {
+        KeResetEvent(Event);
+    }
+
+    Offset.QuadPart = 0LL;
+    Irp = IoBuildSynchronousFsdRequest(Code, DeviceObject, (PVOID)StreamHeaders, Length, &Offset, Event, IoStatusBlock);
+    if (!Irp)
+    {
+        return STATUS_UNSUCCESSFUL;
+    }
+
+
+    if (CompletionRoutine)
+    {
+        IoSetCompletionRoutine(Irp,
+                               CompletionRoutine,
+                               CompletionContext,
+                               (CompletionInvocationFlags & KsInvokeOnSuccess),
+                               (CompletionInvocationFlags & KsInvokeOnError),
+                               (CompletionInvocationFlags & KsInvokeOnCancel));
+    }
+
+    IoStack = IoGetNextIrpStackLocation(Irp);
+    IoStack->FileObject = FileObject;
+
+    Status = IoCallDriver(DeviceObject, Irp);
+    return Status;
 }
 
 /*

Propchange: trunk/reactos/drivers/wdm/audio/backpln/audio_test/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Sat Feb 21 23:18:44 2009
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)

Propchange: trunk/reactos/drivers/wdm/audio/backpln/audio_test/
------------------------------------------------------------------------------
    bugtraq:message = See issue #%BUGID% for more details.

Propchange: trunk/reactos/drivers/wdm/audio/backpln/audio_test/
------------------------------------------------------------------------------
    bugtraq:url = http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%

Propchange: trunk/reactos/drivers/wdm/audio/backpln/audio_test/
------------------------------------------------------------------------------
    tsvn:logminsize = 10

Added: trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c?rev=39702&view=auto
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c (added)
+++ trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c [iso-8859-1] Sat Feb 21 23:18:44 2009
@@ -1,0 +1,152 @@
+#define _UNICODE
+#define UNICODE
+#include <windows.h>
+#include <mmsystem.h>
+#include <stdio.h>
+#include <math.h>
+
+#define _2pi                6.283185307179586476925286766559
+
+#include <ks.h>
+#include <ksmedia.h>
+#include "interface.h"
+
+int
+__cdecl
+main(int argc, char* argv[])
+{
+    ULONG Length;
+    PSHORT SoundBuffer;
+    ULONG i = 0;
+    BOOL Status;
+    OVERLAPPED Overlapped;
+    DWORD BytesReturned;
+    HANDLE hWdmAud;
+    WDMAUD_DEVICE_INFO DeviceInfo;
+
+
+    hWdmAud = CreateFileW(L"\\\\.\\wdmaud",
+                          GENERIC_READ | GENERIC_WRITE,
+                          0,
+                          NULL,
+                          OPEN_EXISTING,
+                          FILE_FLAG_OVERLAPPED,
+                          NULL);
+     if (!hWdmAud)
+     {
+         printf("Failed to open wdmaud with %lx\n", GetLastError());
+         return -1;
+     }
+
+     printf("WDMAUD: opened\n");
+     /* clear device info */
+     RtlZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
+
+     ZeroMemory(&Overlapped, sizeof(OVERLAPPED));
+     Overlapped.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+
+     DeviceInfo.DeviceType = WAVE_OUT_DEVICE_TYPE;
+
+     Status = DeviceIoControl(hWdmAud, IOCTL_GETNUMDEVS_TYPE, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped);
+
+     if (!Status)
+     {
+         if (WaitForSingleObject(&Overlapped.hEvent, 5000) != WAIT_OBJECT_0)
+         {
+            printf("Failed to get num of wave out devices with %lx\n", GetLastError());
+            CloseHandle(hWdmAud);
+            return -1;
+         }
+     }
+
+     printf("WDMAUD: Num Devices %lu\n", DeviceInfo.DeviceCount);
+     if (!DeviceInfo.DeviceCount)
+     {
+        CloseHandle(hWdmAud);
+        return 0;
+    }
+
+    DeviceInfo.u.WaveFormatEx.cbSize = sizeof(WAVEFORMATEX);
+    DeviceInfo.u.WaveFormatEx.wFormatTag = 0x1; //WAVE_FORMAT_PCM;
+    DeviceInfo.u.WaveFormatEx.nChannels = 2;
+    DeviceInfo.u.WaveFormatEx.nSamplesPerSec = 48000;
+    DeviceInfo.u.WaveFormatEx.nBlockAlign = 4;
+    DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 48000 * 4;
+    DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16;
+
+
+
+     Status = DeviceIoControl(hWdmAud, IOCTL_OPEN_WDMAUD, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped);
+     if (!Status)
+     {
+         if (WaitForSingleObject(&Overlapped.hEvent, 5000) != WAIT_OBJECT_0)
+         {
+             printf("Failed to open device with %lx\n", GetLastError());
+             CloseHandle(hWdmAud);
+             return -1;
+         }
+     }
+
+    //
+    // Allocate a buffer for 1 second
+    //
+    Length = 48000 * 4;
+    SoundBuffer = (PSHORT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length);
+
+    //
+    // Fill the buffer with a 500 Hz sine tone
+    //
+    while (i < Length / 2)
+    {
+        //
+        // Generate the wave for each channel:
+        // Amplitude * sin( Sample * Frequency * 2PI / SamplesPerSecond )
+        //
+        SoundBuffer[i] = 0x7FFF * sin(0.5 * (i - 1) * 500 * _2pi / 48000);
+        i++;
+        SoundBuffer[i] = 0x7FFF * sin((0.5 * i - 2) * 500 * _2pi / 48000);
+        i++;
+    }
+
+    DeviceInfo.State = KSSTATE_RUN;
+    Status = DeviceIoControl(hWdmAud, IOCTL_SETDEVICE_STATE, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped);
+    if (!Status)
+    {
+         if (WaitForSingleObject(&Overlapped.hEvent, 5000) != WAIT_OBJECT_0)
+         {
+             printf("Failed to set device into run state %lx\n", GetLastError());
+             CloseHandle(hWdmAud);
+             return -1;
+         }
+    }
+
+    //
+    // Play our 1-second buffer
+    //
+    DeviceInfo.Buffer = (PUCHAR)SoundBuffer;
+    DeviceInfo.BufferSize = Length;
+    Status = DeviceIoControl(hWdmAud, IOCTL_WRITEDATA, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped);
+    if (!Status)
+    {
+         if (WaitForSingleObject(&Overlapped.hEvent, 5000) != WAIT_OBJECT_0)
+         {
+             printf("Failed to play buffer %lx\n", GetLastError());
+             CloseHandle(hWdmAud);
+             return -1;
+         }
+    }
+
+    DeviceInfo.State = KSSTATE_STOP;
+    Status = DeviceIoControl(hWdmAud, IOCTL_SETDEVICE_STATE, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped);
+    if (!Status)
+    {
+         if (WaitForSingleObject(&Overlapped.hEvent, 5000) != WAIT_OBJECT_0)
+         {
+             printf("Failed to set device into stop state %lx\n", GetLastError());
+             CloseHandle(hWdmAud);
+            return -1;
+         }
+    }
+    CloseHandle(hWdmAud);
+    return 0;
+}

Propchange: trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.rbuild?rev=39702&view=auto
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.rbuild (added)
+++ trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.rbuild [iso-8859-1] Sat Feb 21 23:18:44 2009
@@ -1,0 +1,11 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../../../tools/rbuild/project.dtd">
+<module name="audio_test" type="win32cui" installbase="system32" installname="audio_test.exe">
+	<define name="PC_NO_IMPORTS" />
+	<include base="ReactOS">include/reactos/libs/sound</include>
+	<include base="wdmaud_kernel">.</include>
+	<library>kernel32</library>
+
+	<file>audio_test.c</file>
+
+</module>

Propchange: trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.rbuild
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/reactos/drivers/wdm/audio/backpln/directory.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/directory.rbuild?rev=39702&r1=39701&r2=39702&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/directory.rbuild [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/directory.rbuild [iso-8859-1] Sat Feb 21 23:18:44 2009
@@ -1,6 +1,9 @@
 <?xml version="1.0"?>
 <!DOCTYPE group SYSTEM "../../../../tools/rbuild/project.dtd">
 <group xmlns:xi="http://www.w3.org/2001/XInclude">
+	<directory name="audio_test">
+		<xi:include href="audio_test/audio_test.rbuild" />
+	</directory>
 	<directory name="portcls">
 		<xi:include href="portcls/portcls.rbuild" />
 	</directory>

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c?rev=39702&r1=39701&r2=39702&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1] Sat Feb 21 23:18:44 2009
@@ -350,7 +350,7 @@
 {
     PKSPROPERTY Property;
     NTSTATUS Status;
-    UNICODE_STRING GuidString, GuidString2;
+    UNICODE_STRING GuidString;
     PIO_STACK_LOCATION IoStack;
     IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
 
@@ -413,6 +413,7 @@
                         This->State = *State;
                         Irp->IoStatus.Information = sizeof(KSSTATE);
                         Irp->IoStatus.Status = Status;
+                        IoCompleteRequest(Irp, IO_NO_INCREMENT);
                         return Status;
                     }
                     Irp->IoStatus.Status = Status;
@@ -484,11 +485,9 @@
 
     }
     RtlStringFromGUID(&Property->Set, &GuidString);
-    RtlStringFromGUID(&KSPROPSETID_Connection, &GuidString2);
-    DPRINT1("Unhandeled property Set |%S| |%S|Id %u Flags %x\n", GuidString.Buffer, GuidString2.Buffer, Property->Id, Property->Flags);
+    DPRINT1("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
     DbgBreakPoint();
     RtlFreeUnicodeString(&GuidString);
-    RtlFreeUnicodeString(&GuidString2);
 
     Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
     Irp->IoStatus.Information = 0;

Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c?rev=39702&r1=39701&r2=39702&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] Sat Feb 21 23:18:44 2009
@@ -8,6 +8,322 @@
  */
 #include "wdmaud.h"
 
+const GUID KSPROPSETID_Connection               = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
+const GUID KSPROPSETID_Sysaudio                 = {0xCBE3FAA0L, 0xCC75, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}};
+const GUID KSPROPSETID_General                  = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
+const GUID KSINTERFACESETID_Standard            = {0x1A8766A0L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
+const GUID KSMEDIUMSETID_Standard               = {0x4747B320L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
+const GUID KSDATAFORMAT_TYPE_AUDIO              = {0x73647561L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+const GUID KSDATAFORMAT_SUBTYPE_PCM             = {0x00000001L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX  = {0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
+
+
+NTSTATUS
+SetIrpIoStatus(
+    IN PIRP Irp,
+    IN NTSTATUS Status,
+    IN ULONG Length)
+{
+    Irp->IoStatus.Information = Length;
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return Status;
+
+}
+
+NTSTATUS
+WdmAudControlOpen(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  PIRP Irp,
+    IN  PWDMAUD_DEVICE_INFO DeviceInfo,
+    IN  PWDMAUD_CLIENT ClientInfo)
+{
+    PSYSAUDIO_INSTANCE_INFO InstanceInfo;
+    ULONG BytesReturned;
+    NTSTATUS Status;
+    ACCESS_MASK DesiredAccess = 0;
+    HANDLE PinHandle;
+    KSPIN_CONNECT * PinConnect;
+    KSDATAFORMAT_WAVEFORMATEX * DataFormat;
+
+    if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE)
+    {
+        DPRINT1("FIXME: only waveout devices are supported\n");
+        return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+    }
+
+    InstanceInfo = ExAllocatePool(NonPagedPool, sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT));
+    if (!InstanceInfo)
+    {
+        /* no memory */
+        return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+    }
+
+    InstanceInfo->Property.Set = KSPROPSETID_Sysaudio;
+    InstanceInfo->Property.Id = KSPROPERTY_SYSAUDIO_INSTANCE_INFO;
+    InstanceInfo->Property.Flags = KSPROPERTY_TYPE_SET;
+    InstanceInfo->Flags = 0;
+    InstanceInfo->DeviceNumber = DeviceInfo->DeviceIndex;
+
+    Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, sizeof(SYSAUDIO_INSTANCE_INFO), NULL, 0, &BytesReturned);
+
+    if (!NT_SUCCESS(Status))
+    {
+        /* failed to acquire audio device */
+        DPRINT1("KsSynchronousIoControlDevice failed with %x\n", Status);
+        ExFreePool(InstanceInfo);
+        return SetIrpIoStatus(Irp, Status, 0);
+    }
+
+    if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE ||
+        DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE ||
+        DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
+    {
+        DesiredAccess |= GENERIC_READ;
+    }
+
+    if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE ||
+        DeviceInfo->DeviceType == MIDI_OUT_DEVICE_TYPE ||
+        DeviceInfo->DeviceType == AUX_DEVICE_TYPE ||
+        DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
+    {
+        DesiredAccess |= GENERIC_WRITE;
+    }
+
+    PinConnect = (KSPIN_CONNECT*)InstanceInfo;
+
+
+    PinConnect->Interface.Set = KSINTERFACESETID_Standard;
+    PinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING;
+    PinConnect->Interface.Flags = 0;
+    PinConnect->Medium.Set = KSMEDIUMSETID_Standard;
+    PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE;
+    PinConnect->Medium.Flags = 0;
+    PinConnect->PinId = 0; //FIXME
+    PinConnect->PinToHandle = NULL;
+    PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
+    PinConnect->Priority.PrioritySubClass = 1;
+
+
+    DataFormat = (KSDATAFORMAT_WAVEFORMATEX*) (PinConnect + 1);
+    DataFormat->WaveFormatEx.wFormatTag = DeviceInfo->u.WaveFormatEx.wFormatTag;
+    DataFormat->WaveFormatEx.nChannels = DeviceInfo->u.WaveFormatEx.nChannels;
+    DataFormat->WaveFormatEx.nSamplesPerSec = DeviceInfo->u.WaveFormatEx.nSamplesPerSec;
+    DataFormat->WaveFormatEx.nBlockAlign = DeviceInfo->u.WaveFormatEx.nBlockAlign;
+    DataFormat->WaveFormatEx.nAvgBytesPerSec = DeviceInfo->u.WaveFormatEx.nAvgBytesPerSec;
+    DataFormat->WaveFormatEx.wBitsPerSample = DeviceInfo->u.WaveFormatEx.wBitsPerSample;
+    DataFormat->WaveFormatEx.cbSize = 0;
+    DataFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX);
+    DataFormat->DataFormat.Flags = 0;
+    DataFormat->DataFormat.Reserved = 0;
+    DataFormat->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
+
+    if (DeviceInfo->u.WaveFormatEx.wFormatTag != WAVE_FORMAT_PCM)
+        DPRINT1("FIXME\n");
+
+    DataFormat->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+    DataFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
+    DataFormat->DataFormat.SampleSize = 4;
+
+
+    Status = KsCreatePin(ClientInfo->hSysAudio, PinConnect, DesiredAccess, &PinHandle);
+    DPRINT1("KsCreatePin Status %x\n", Status);
+
+
+    /* free buffer */
+    ExFreePool(InstanceInfo);
+
+    if (NT_SUCCESS(Status))
+    {
+        DeviceInfo->hDevice = PinHandle;
+    }
+    else
+    {
+        DeviceInfo->hDevice = NULL;
+    }
+
+    return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+}
+
+NTSTATUS
+WdmAudControlDeviceType(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  PIRP Irp,
+    IN  PWDMAUD_DEVICE_INFO DeviceInfo,
+    IN  PWDMAUD_CLIENT ClientInfo)
+{
+    KSPROPERTY Property;
+    ULONG Result, BytesReturned;
+    NTSTATUS Status;
+
+    if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE)
+    {
+        DPRINT1("FIXME: only waveout devices are supported\n");
+        return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+    }
+
+    Property.Set = KSPROPSETID_Sysaudio;
+    Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
+    Property.Flags = KSPROPERTY_TYPE_GET;
+
+    Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&Result, sizeof(ULONG), &BytesReturned);
+
+    if (NT_SUCCESS(Status))
+        DeviceInfo->DeviceCount = Result;
+    else
+        DeviceInfo->DeviceCount = 0;
+
+    DPRINT1("WdmAudControlDeviceType Status %x Devices %u\n", Status, DeviceInfo->DeviceCount);
+    return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+}
+
+NTSTATUS
+WdmAudControlDeviceState(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  PIRP Irp,
+    IN  PWDMAUD_DEVICE_INFO DeviceInfo,
+    IN  PWDMAUD_CLIENT ClientInfo)
+{
+    KSPROPERTY Property;
+    KSSTATE State;
+    NTSTATUS Status;
+    ULONG BytesReturned;
+    PFILE_OBJECT FileObject;
+
+    if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE)
+    {
+        DPRINT1("FIXME: only waveout devices are supported\n");
+        return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+    }
+
+    Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Error: invalid device handle provided %p\n", DeviceInfo->hDevice);
+        return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+    }
+
+    Property.Set = KSPROPSETID_Connection;
+    Property.Id = KSPROPERTY_CONNECTION_STATE;
+    Property.Flags = KSPROPERTY_TYPE_SET;
+
+    State = DeviceInfo->State;
+
+    Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&State, sizeof(KSSTATE), &BytesReturned);
+
+    ObDereferenceObject(FileObject);
+
+    DPRINT1("WdmAudControlDeviceState Status %x\n", Status);
+    return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+}
+
+NTSTATUS
+NTAPI
+WdmAudWriteCompleted(
+    IN PDEVICE_OBJECT  DeviceObject,
+    IN PIRP  Irp,
+    IN PVOID  Ctx)
+{
+    PWRITE_CONTEXT Context = (PWRITE_CONTEXT)Ctx;
+
+    Context->Irp->IoStatus.Information = Context->Length;
+    Context->Irp->IoStatus.Status = Irp->IoStatus.Status;
+    IoCompleteRequest(Context->Irp, IO_SOUND_INCREMENT);
+
+    ExFreePool(Context);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+WdmAudControlWriteData(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  PIRP Irp,
+    IN  PWDMAUD_DEVICE_INFO DeviceInfo,
+    IN  PWDMAUD_CLIENT ClientInfo)
+{
+    PKSSTREAM_HEADER Packet;
+    NTSTATUS Status = STATUS_SUCCESS;
+    PFILE_OBJECT FileObject;
+    PWRITE_CONTEXT Context;
+    ULONG BytesReturned;
+    PUCHAR Buffer;
+
+    Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Invalid buffer handle %x\n", DeviceInfo->hDevice);
+        return SetIrpIoStatus(Irp, Status, 0);
+    }
+
+    if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE)
+    {
+        DPRINT1("FIXME: only waveout devices are supported\n");
+        return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+    }
+
+    _SEH2_TRY
+    {
+        ProbeForRead(DeviceInfo->Buffer, DeviceInfo->BufferSize, TYPE_ALIGNMENT(char));
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        /* Exception, get the error code */
+        Status = _SEH2_GetExceptionCode();
+    }
+    _SEH2_END;
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Invalid buffer supplied\n");
+        return SetIrpIoStatus(Irp, Status, 0);
+    }
+
+    Buffer = ExAllocatePool(NonPagedPool, DeviceInfo->BufferSize);
+    if (!Buffer)
+    {
+        /* no memory */
+        return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+    }
+
+    RtlMoveMemory(Buffer, DeviceInfo->Buffer, DeviceInfo->BufferSize);
+
+
+    Context = ExAllocatePool(NonPagedPool, sizeof(WRITE_CONTEXT));
+    if (!Context)
+    {
+        /* no memory */
+        return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+    }
+
+    /* setup completion context */
+    Context->Irp = Irp;
+    Context->Length = DeviceInfo->BufferSize;
+
+    /* setup stream context */
+    Packet = (PKSSTREAM_HEADER)ExAllocatePool(NonPagedPool, sizeof(KSSTREAM_HEADER));
+    Packet->Data = Buffer;
+    Packet->FrameExtent = DeviceInfo->BufferSize;
+    Packet->DataUsed = DeviceInfo->BufferSize;
+    Packet->Size = sizeof(KSSTREAM_HEADER);
+    Packet->PresentationTime.Numerator = 1;
+    Packet->PresentationTime.Denominator = 1;
+    ASSERT(FileObject->FsContext != NULL);
+
+
+    Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_WRITE_STREAM, (PVOID)Packet, sizeof(KSSTREAM_HEADER), NULL, 0, &BytesReturned);
+
+    DPRINT1("KsSynchronousIoControlDevice result %x\n", Status);
+
+    IoMarkIrpPending(Irp);
+    Irp->IoStatus.Information = DeviceInfo->BufferSize;
+    Irp->IoStatus.Status = Status;
+
+    ExFreePool(Buffer);
+
+    return Status;
+}
+
+
 
 NTSTATUS
 NTAPI
@@ -16,42 +332,59 @@
     IN  PIRP Irp)
 {
     PIO_STACK_LOCATION IoStack;
+    PWDMAUD_DEVICE_INFO DeviceInfo;
+    PWDMAUD_CLIENT ClientInfo;
 
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
+    DPRINT1("WdmAudDeviceControl entered\n");
+    DbgBreakPoint();
+
     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;
-    }
+        /* invalid parameter */
+        DPRINT1("Input buffer too small size %u expected %u\n", IoStack->Parameters.DeviceIoControl.InputBufferLength, sizeof(WDMAUD_DEVICE_INFO));
+        return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
+    }
+
+    DeviceInfo = (PWDMAUD_DEVICE_INFO)Irp->AssociatedIrp.SystemBuffer;
+
+    if (DeviceInfo->DeviceType < MIN_SOUND_DEVICE_TYPE || DeviceInfo->DeviceType > MAX_SOUND_DEVICE_TYPE)
+    {
+        /* invalid parameter */
+        DPRINT1("Error: device type not set\n");
+        return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
+    }
+
+    if (!IoStack->FileObject)
+    {
+        /* file object parameter */
+        DPRINT1("Error: file object is not attached\n");
+        return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+    }
+    ClientInfo = (PWDMAUD_CLIENT)IoStack->FileObject->FsContext;
 
     DPRINT1("WdmAudDeviceControl entered\n");
 
     switch(IoStack->Parameters.DeviceIoControl.IoControlCode)
     {
         case IOCTL_OPEN_WDMAUD:
-            //return WdmAudDeviceControlOpen(DeviceObject, Irp);
+            return WdmAudControlOpen(DeviceObject, Irp, DeviceInfo, ClientInfo);
+        case IOCTL_GETNUMDEVS_TYPE:
+            return WdmAudControlDeviceType(DeviceObject, Irp, DeviceInfo, ClientInfo);
+        case IOCTL_SETDEVICE_STATE:
+            return WdmAudControlDeviceState(DeviceObject, Irp, DeviceInfo, ClientInfo);
+        case IOCTL_WRITEDATA:
+            return WdmAudControlWriteData(DeviceObject, Irp, DeviceInfo, ClientInfo);
+
         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:
+           DPRINT1("Unhandeled %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
            break;
     }
 
-
-
-
-    UNIMPLEMENTED
-
-    Irp->IoStatus.Status = STATUS_SUCCESS;
-    Irp->IoStatus.Information = 0;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return STATUS_SUCCESS;
-}
+    return SetIrpIoStatus(Irp, STATUS_NOT_IMPLEMENTED, 0);
+}

Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c?rev=39702&r1=39701&r2=39702&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c [iso-8859-1] Sat Feb 21 23:18:44 2009
@@ -120,7 +120,7 @@
     NTSTATUS Status;
 
     PIO_STACK_LOCATION IoStack;
-    WDMAUD_CLIENT *pClient;
+    PWDMAUD_CLIENT pClient;
 
     PWDMAUD_DEVICE_EXTENSION DeviceExtension;
 
@@ -189,11 +189,11 @@
     pClient = (WDMAUD_CLIENT*)IoStack->FileObject->FsContext;
     if (pClient)
     {
+        ObDereferenceObject(pClient->FileObject);
         ZwClose(pClient->hSysAudio);
         ExFreePool(pClient);
         IoStack->FileObject->FsContext = NULL;
     }
-
 
     Irp->IoStatus.Status = Status;
     Irp->IoStatus.Information = 0;

Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h?rev=39702&r1=39701&r2=39702&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h [iso-8859-1] Sat Feb 21 23:18:44 2009
@@ -44,7 +44,7 @@
         WAVEINCAPS WaveInCaps;
     }u;
 
-}WDMAUD_DEVICE_INFO;
+}WDMAUD_DEVICE_INFO, *PWDMAUD_DEVICE_INFO;
 
 
 

Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h?rev=39702&r1=39701&r2=39702&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] Sat Feb 21 23:18:44 2009
@@ -1,6 +1,7 @@
 #ifndef WDMAUD_H__
 #define WDMAUD_H__
 
+#include <pseh/pseh2.h>
 #include <ntddk.h>
 #include <portcls.h>
 #include <ks.h>
@@ -86,6 +87,14 @@
 
 }WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION;
 
+typedef struct
+{
+    PIRP Irp;
+    IO_STATUS_BLOCK StatusBlock;
+    ULONG Length;
+}WRITE_CONTEXT, *PWRITE_CONTEXT;
+
+
 NTSTATUS
 WdmAudRegisterDeviceInterface(
     IN PDEVICE_OBJECT PhysicalDeviceObject,

Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild?rev=39702&r1=39701&r2=39702&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild [iso-8859-1] Sat Feb 21 23:18:44 2009
@@ -6,6 +6,7 @@
 	<include base="ReactOS">include/reactos/libs/sound</include>
 	<library>ntoskrnl</library>
 	<library>ks</library>
+	<library>pseh</library>
 	<file>control.c</file>
 	<file>deviface.c</file>
 	<file>entry.c</file>

Modified: trunk/reactos/drivers/wdm/audio/sysaudio/control.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/control.c?rev=39702&r1=39701&r2=39702&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/control.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/control.c [iso-8859-1] Sat Feb 21 23:18:44 2009
@@ -29,6 +29,7 @@
 {
     Irp->IoStatus.Information = Length;
     Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
     return Status;
 
 }
@@ -242,7 +243,7 @@
         }
         else if (Property->Id == KSPROPERTY_SYSAUDIO_INSTANCE_INFO)
         {
-            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SYSAUDIO_INSTANCE_INFO))
+            if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SYSAUDIO_INSTANCE_INFO))
             {
                 /* too small buffer */
                 return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(SYSAUDIO_INSTANCE_INFO));

Modified: trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c?rev=39702&r1=39701&r2=39702&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c [iso-8859-1] Sat Feb 21 23:18:44 2009
@@ -52,6 +52,8 @@
             DPRINT1("No Mem\n");
             return STATUS_INSUFFICIENT_RESOURCES;
         }
+
+        RtlZeroMemory(DeviceEntry, sizeof(KSAUDIO_DEVICE_ENTRY));
         DeviceEntry->DeviceName.Length = 0;
         DeviceEntry->DeviceName.MaximumLength = Event->SymbolicLinkName->Length + 5 * sizeof(WCHAR);
         DeviceEntry->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceEntry->DeviceName.MaximumLength);

Modified: trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c?rev=39702&r1=39701&r2=39702&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c [iso-8859-1] Sat Feb 21 23:18:44 2009
@@ -175,6 +175,61 @@
     Dispatch_fnFastWrite,
 };
 
+VOID
+NTAPI
+CreatePinWorkerRoutine(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PVOID  Context)
+{
+    NTSTATUS Status;
+    HANDLE PinHandle;
+    HANDLE * Handels;
+    PFILE_OBJECT FileObject;
+    PIRP Irp;
+    PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context;
+
+    Handels = ExAllocatePool(NonPagedPool, (WorkerContext->Entry->NumberOfPins + 1) * sizeof(HANDLE));
+    if (!Handels)
+    {
+        DPRINT1("No Memory \n");
+        WorkerContext->Irp->IoStatus.Status = STATUS_NO_MEMORY;
+        WorkerContext->Irp->IoStatus.Information = 0;
+        IoCompleteRequest(WorkerContext->Irp, IO_SOUND_INCREMENT);
+        return;
+    }
+
+
+    Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);
+    DPRINT1("KsCreatePin status %x\n", Status);
+
+    if (NT_SUCCESS(Status))
+    {
+         Status = ObReferenceObjectByHandle(PinHandle, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+         if (NT_SUCCESS(Status))
+         {
+             Status = CreateDispatcher(WorkerContext->Irp, PinHandle, FileObject);
+             DPRINT1("Pins %x\n", WorkerContext->Entry->NumberOfPins);
+             if (WorkerContext->Entry->NumberOfPins)
+             {
+                 RtlMoveMemory(Handels, WorkerContext->Entry->Pins, WorkerContext->Entry->NumberOfPins * sizeof(HANDLE));
+                 ExFreePool(WorkerContext->Entry->Pins);
+             }
+             Handels[WorkerContext->Entry->NumberOfPins-1] = PinHandle;
+             WorkerContext->Entry->Pins = Handels;
+             WorkerContext->Entry->NumberOfPins++;
+         }
+    }
+
+    DPRINT1("CreatePinWorkerRoutine completing irp\n");
+    WorkerContext->Irp->IoStatus.Status = Status;
+    WorkerContext->Irp->IoStatus.Information = 0;
+
+    Irp = WorkerContext->Irp;
+    ExFreePool(Context);
+
+    IoCompleteRequest(Irp, IO_SOUND_INCREMENT);
+}
+
 NTSTATUS
 NTAPI
 DispatchCreateSysAudio(
@@ -185,9 +240,79 @@
     KSOBJECT_HEADER ObjectHeader;
     PSYSAUDIO_CLIENT Client;
     PKSOBJECT_CREATE_ITEM CreateItem;
+    PIO_STACK_LOCATION IoStatus;
+    LPWSTR Buffer;
+    ULONG Length, DeviceIndex;
+    PSYSAUDIODEVEXT DeviceExtension;
+    PKSAUDIO_DEVICE_ENTRY Entry;
+    KSPIN_CONNECT * PinConnect;
+    PIO_WORKITEM WorkItem;
+    PPIN_WORKER_CONTEXT Context;
+    static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
+
+    IoStatus = IoGetCurrentIrpStackLocation(Irp);
+    Buffer = IoStatus->FileObject->FileName.Buffer;
 
     DPRINT1("DispatchCreateSysAudio entered\n");
-    DbgBreakPoint();
+
+    if (Buffer)
+    {
+        /* is the request for a new pin */
+        if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN)))
+        {
+            Client = (PSYSAUDIO_CLIENT)Irp->Tail.Overlay.OriginalFileObject->FsContext2;
+            DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
+            if (Client)
+            {
+                ASSERT(Client->NumDevices >= 1);
+                DeviceIndex = Client->Devices[Client->NumDevices-1];
+            }
+            else
+            {
+                DPRINT1("Warning: using HACK\n");
+                DeviceIndex = 0;
+            }
+            ASSERT(DeviceIndex < DeviceExtension->NumberOfKsAudioDevices);
+            Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, DeviceIndex);
+            ASSERT(Entry);
+
+            Length = (IoStatus->FileObject->FileName.Length - ((wcslen(KS_NAME_PIN)+1) * sizeof(WCHAR)));
+            PinConnect = ExAllocatePool(NonPagedPool, Length);
+            if (!PinConnect)
+            {
+                Irp->IoStatus.Status = STATUS_NO_MEMORY;
+                Irp->IoStatus.Information = 0;
+                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                return STATUS_NO_MEMORY;
+            }
+            RtlMoveMemory(PinConnect, IoStatus->FileObject->FileName.Buffer + (wcslen(KS_NAME_PIN)+1), Length);
+            Context = ExAllocatePool(NonPagedPool, sizeof(PIN_WORKER_CONTEXT));
+            if (!Context)
+            {
+                Irp->IoStatus.Information = 0;
+                Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
+                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                return STATUS_INSUFFICIENT_RESOURCES;
+            }
+            Context->PinConnect = PinConnect;
+            Context->Entry = Entry;
+            Context->Irp = Irp;
+
+            WorkItem = IoAllocateWorkItem(DeviceObject);
+            if (!WorkItem)
+            {
+                Irp->IoStatus.Information = 0;
+                Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
+                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                return STATUS_INSUFFICIENT_RESOURCES;
+            }
+            IoQueueWorkItem(WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
+            Irp->IoStatus.Information = 0;
+            Irp->IoStatus.Status = STATUS_PENDING;
+            IoMarkIrpPending(Irp);
+            return STATUS_PENDING;
+        }
+    }
 
     /* allocate create item */
     CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
@@ -209,6 +334,9 @@
     /* store create context */
     CreateItem->Context = (PVOID)Client;
 
+    /* store the object in FsContext */
+    IoStatus->FileObject->FsContext2 = (PVOID)Client;
+
     /* allocate object header */
     Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);
 
@@ -228,8 +356,6 @@
     if (!CreateItem)
         return STATUS_INSUFFICIENT_RESOURCES;
 
-
-
     /* initialize create item struct */
     RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
     CreateItem->Create = DispatchCreateSysAudio;
@@ -238,7 +364,6 @@
     Status = KsAllocateDeviceHeader(&DeviceExtension->KsDeviceHeader,
                                     1,
                                     CreateItem);
-
     return Status;
 }
 

Added: trunk/reactos/drivers/wdm/audio/sysaudio/pin.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/pin.c?rev=39702&view=auto
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/pin.c (added)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/pin.c [iso-8859-1] Sat Feb 21 23:18:44 2009
@@ -1,0 +1,261 @@
+/*
+ * 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"
+
+NTSTATUS
+NTAPI
+Pin_fnDeviceIoControl(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
+{
+    PDISPATCH_CONTEXT Context;
+    PKSOBJECT_CREATE_ITEM CreateItem;
+    NTSTATUS Status;
+    ULONG BytesReturned;
+    PIO_STACK_LOCATION IoStack;
+
+    DPRINT1("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
+
+    /* access the create item */
+    CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
+    Context = (PDISPATCH_CONTEXT)CreateItem->Context;
+
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IoStack->Parameters.DeviceIoControl.IoControlCode,
+                                          IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
+                                          IoStack->Parameters.DeviceIoControl.InputBufferLength,
+                                          Irp->UserBuffer,
+                                          IoStack->Parameters.DeviceIoControl.OutputBufferLength,
+                                          &BytesReturned);
+
+    DPRINT1("Status %x\n", Status);
+
+    Irp->IoStatus.Information = BytesReturned;
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+Pin_fnRead(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
+{
+    DPRINT1("Pin_fnRead called DeviceObject %p Irp %p\n", DeviceObject);
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+PinWriteCompletionRoutine(
+    IN PDEVICE_OBJECT  DeviceObject,
+    IN PIRP  Irp,
+    IN PVOID  Context)
+{
+    PIRP CIrp = (PIRP)Context;
+
+    CIrp->IoStatus.Status = STATUS_SUCCESS;
+    CIrp->IoStatus.Information = 0;
+    IoCompleteRequest(CIrp, IO_NO_INCREMENT);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+Pin_fnWrite(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
+{
+    PDISPATCH_CONTEXT Context;
+    PKSOBJECT_CREATE_ITEM CreateItem;
+    PIO_STACK_LOCATION IoStack;
+    ULONG BytesReturned;
+    NTSTATUS Status;
+
+    DPRINT1("Pin_fnWrite called DeviceObject %p Irp %p\n", DeviceObject);
+
+   /* access the create item */
+    CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
+    Context = (PDISPATCH_CONTEXT)CreateItem->Context;
+
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IOCTL_KS_WRITE_STREAM,
+                                          IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
+                                          IoStack->Parameters.DeviceIoControl.InputBufferLength,
+                                          Irp->UserBuffer,
+                                          IoStack->Parameters.DeviceIoControl.OutputBufferLength,
+                                          &BytesReturned);
+
+    Irp->IoStatus.Information = BytesReturned;
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+Pin_fnFlush(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
+{
+    DPRINT1("Pin_fnFlush called DeviceObject %p Irp %p\n", DeviceObject);
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+Pin_fnClose(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
+{
+    DPRINT1("Pin_fnClose called DeviceObject %p Irp %p\n", DeviceObject);
+
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+Pin_fnQuerySecurity(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
+{
+    DPRINT1("Pin_fnQuerySecurity called DeviceObject %p Irp %p\n", DeviceObject);
+
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+Pin_fnSetSecurity(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
+{
+
+    DPRINT1("Pin_fnSetSecurity called DeviceObject %p Irp %p\n", DeviceObject);
+
+    return STATUS_SUCCESS;
+}
+
+BOOLEAN
+NTAPI
+Pin_fnFastDeviceIoControl(
+    PFILE_OBJECT FileObject,
+    BOOLEAN Wait,
+    PVOID InputBuffer,
+    ULONG InputBufferLength,
+    PVOID OutputBuffer,
+    ULONG OutputBufferLength,
+    ULONG IoControlCode,
+    PIO_STATUS_BLOCK IoStatus,
+    PDEVICE_OBJECT DeviceObject)
+{
+    DPRINT1("Pin_fnFastDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
+
+
+    return FALSE;
+}
+
+
+BOOLEAN
+NTAPI
+Pin_fnFastRead(
+    PFILE_OBJECT FileObject,
+    PLARGE_INTEGER FileOffset,
+    ULONG Length,
+    BOOLEAN Wait,
+    ULONG LockKey,
+    PVOID Buffer,
+    PIO_STATUS_BLOCK IoStatus,
+    PDEVICE_OBJECT DeviceObject)
+{
+    DPRINT1("Pin_fnFastRead called DeviceObject %p Irp %p\n", DeviceObject);
+
+    return FALSE;
+
+}
+
+BOOLEAN
+NTAPI
+Pin_fnFastWrite(
+    PFILE_OBJECT FileObject,
+    PLARGE_INTEGER FileOffset,
+    ULONG Length,
+    BOOLEAN Wait,
+    ULONG LockKey,
+    PVOID Buffer,
+    PIO_STATUS_BLOCK IoStatus,
+    PDEVICE_OBJECT DeviceObject)
+{
+    DPRINT1("Pin_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject);
+
+    return FALSE;
+}
+
+static KSDISPATCH_TABLE PinTable =
+{
+    Pin_fnDeviceIoControl,
+    Pin_fnRead,
+    Pin_fnWrite,
+    Pin_fnFlush,
+    Pin_fnClose,
+    Pin_fnQuerySecurity,
+    Pin_fnSetSecurity,
+    Pin_fnFastDeviceIoControl,
+    Pin_fnFastRead,
+    Pin_fnFastWrite,
+};
+
+NTSTATUS
+CreateDispatcher(
+    IN PIRP Irp,
+    IN HANDLE Handle,
+    IN PFILE_OBJECT FileObject)
+{
+    PKSOBJECT_CREATE_ITEM CreateItem;
+    NTSTATUS Status;
+    KSOBJECT_HEADER ObjectHeader;
+    PDISPATCH_CONTEXT Context;
+
+    /* allocate create item */
+    CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
+    if (!CreateItem)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    Context = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT));
+    if (!Context)
+    {
+        ExFreePool(CreateItem);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    Context->Handle = Handle;
+    Context->FileObject = FileObject;
+
+
+     CreateItem->Context = (PVOID)Context;
+
+    /* allocate object header */
+    Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &PinTable);
+    return Status;
+}

Propchange: trunk/reactos/drivers/wdm/audio/sysaudio/pin.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h?rev=39702&r1=39701&r2=39702&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] Sat Feb 21 23:18:44 2009
@@ -15,16 +15,19 @@
     HANDLE Handle;
     PFILE_OBJECT FileObject;
     UNICODE_STRING DeviceName;
+    ULONG NumberOfClients;
 
-    ULONG NumberOfClients;
+    ULONG NumberOfPins;
+    HANDLE * Pins;
+
 }KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY;
 
 
 typedef struct
 {
+    KSDEVICE_HEADER KsDeviceHeader;
     PDEVICE_OBJECT PhysicalDeviceObject;
     PDEVICE_OBJECT NextDeviceObject;
-    KSDEVICE_HEADER KsDeviceHeader;
     ULONG NumberOfKsAudioDevices;
 
     LIST_ENTRY KsAudioDeviceList;
@@ -32,6 +35,20 @@
     PVOID EchoCancelNotificationEntry;
     KMUTEX Mutex;
 }SYSAUDIODEVEXT, *PSYSAUDIODEVEXT;
+
+typedef struct
+{
+    PIRP Irp;
+    PKSAUDIO_DEVICE_ENTRY Entry;
+    KSPIN_CONNECT * PinConnect;
+
+}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT;
+
+typedef struct
+{
+    HANDLE Handle;
+    PFILE_OBJECT FileObject;
+}DISPATCH_CONTEXT, *PDISPATCH_CONTEXT;
 
 NTSTATUS
 SysAudioAllocateDeviceHeader(
@@ -51,4 +68,15 @@
     PDEVICE_OBJECT DeviceObject,
     PIRP Irp);
 
+PKSAUDIO_DEVICE_ENTRY
+GetListEntry(
+    IN PLIST_ENTRY Head,
+    IN ULONG Index);
+
+NTSTATUS
+CreateDispatcher(
+    IN PIRP Irp,
+    IN HANDLE Handle,
+    IN PFILE_OBJECT FileObject);
+
 #endif

Modified: trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.rbuild?rev=39702&r1=39701&r2=39702&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.rbuild [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.rbuild [iso-8859-1] Sat Feb 21 23:18:44 2009
@@ -4,11 +4,13 @@
 	<include base="sysaudio">.</include>
 	<library>ntoskrnl</library>
 	<library>ks</library>
+	<library>hal</library>
 	<library>libcntpr</library>
 	<define name="_COMDDK_" />
 	<file>control.c</file>
 	<file>deviface.c</file>
 	<file>dispatcher.c</file>
 	<file>main.c</file>
+	<file>pin.c</file>
 	<file>sysaudio.rc</file>
 </module>



More information about the Ros-diffs mailing list