Sync to trunk (r44371)
[reactos.git] / reactos / drivers / wdm / audio / legacy / wdmaud / control.c
index 4bfcead..9f51bf4 100644 (file)
@@ -17,112 +17,8 @@ const GUID KSMEDIUMSETID_Standard               = {0x4747B320L, 0x62CE, 0x11CF,
 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}};
+const GUID KSPROPSETID_Topology                 = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
 
-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
-GetFilterIdAndPinId(
-    IN  PDEVICE_OBJECT DeviceObject,
-    IN  PWDMAUD_DEVICE_INFO DeviceInfo,
-    IN  PWDMAUD_CLIENT ClientInfo,
-    IN PULONG FilterId,
-    IN PULONG PinId)
-{
-    KSP_PIN Pin;
-    ULONG Count, BytesReturned, Index, SubIndex, Result, NumPins;
-    NTSTATUS Status;
-    KSPIN_COMMUNICATION Communication;
-    KSPIN_DATAFLOW DataFlow;
-
-    if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE)
-    {
-        DPRINT1("FIXME: Unsupported device type %x\n", DeviceInfo->DeviceType);
-        return STATUS_UNSUCCESSFUL;
-    }
-
-    Pin.Property.Set = KSPROPSETID_Sysaudio;
-    Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
-    Pin.Property.Flags = KSPROPERTY_TYPE_GET;
-
-    Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned);
-    if (!NT_SUCCESS(Status))
-        return STATUS_UNSUCCESSFUL;
-
-    Result = 0;
-    for(Index = 0; Index < Count; Index++)
-    {
-        /* query number of pins */
-        Pin.Reserved = Index; // see sysaudio
-        Pin.Property.Flags = KSPROPERTY_TYPE_GET;
-        Pin.Property.Set = KSPROPSETID_Pin;
-        Pin.Property.Id = KSPROPERTY_PIN_CTYPES;
-        Pin.PinId = 0;
-
-        Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG), &BytesReturned);
-        if (NT_SUCCESS(Status))
-        {
-            /* enumerate now all pins */
-            for(SubIndex = 0; SubIndex < NumPins; SubIndex++)
-            {
-                Pin.PinId = SubIndex;
-                Pin.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
-                Communication = KSPIN_COMMUNICATION_NONE;
-
-                /* get pin communication type */
-                KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned);
-
-                Pin.Property.Id = KSPROPERTY_PIN_DATAFLOW;
-                DataFlow = 0;
-
-                /* get pin dataflow type */
-                KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned);
-
-                if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
-                {
-                    if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_IN)
-                    {
-                        if(DeviceInfo->DeviceIndex == Result)
-                        {
-                            /* found the index */
-                            *FilterId = Index;
-                            *PinId = SubIndex;
-                            return STATUS_SUCCESS;
-                        }
-
-                        Result++;
-                    }
-                }
-                else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
-                {
-                    if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_OUT)
-                    {
-                        if(DeviceInfo->DeviceIndex == Result)
-                        {
-                            /* found the index */
-                            *FilterId = Index;
-                            *PinId = SubIndex;
-                            return STATUS_SUCCESS;
-                        }
-                        Result++;
-                    }
-                }
-            }
-        }
-    }
-
-    return STATUS_UNSUCCESSFUL;
-}
 
 NTSTATUS
 WdmAudControlOpen(
@@ -131,144 +27,17 @@ WdmAudControlOpen(
     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;
-    ULONG Length, Index;
-    KSDATAFORMAT_WAVEFORMATEX * DataFormat;
-    ULONG FilterId;
-    ULONG PinId;
-
-    if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE)
-    {
-        DPRINT1("FIXME: only waveout / wavein devices are supported\n");
-        return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
-    }
-
-    Status = GetFilterIdAndPinId(DeviceObject, DeviceInfo, ClientInfo, &FilterId, &PinId);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("Invalid device index %u\n", DeviceInfo->DeviceIndex);
-        return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
-    }
-
-    Length = sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO);
-    InstanceInfo = ExAllocatePool(NonPagedPool, Length);
-    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 = FilterId;
-
-    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)
+    if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
     {
-        DesiredAccess |= GENERIC_READ;
+        return WdmAudControlOpenMixer(DeviceObject, Irp, DeviceInfo, ClientInfo);
     }
 
-    if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE ||
-        DeviceInfo->DeviceType == MIDI_OUT_DEVICE_TYPE ||
-        DeviceInfo->DeviceType == AUX_DEVICE_TYPE ||
-        DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
+    if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
     {
-        DesiredAccess |= GENERIC_WRITE;
+        return WdmAudControlOpenWave(DeviceObject, Irp, DeviceInfo, ClientInfo);
     }
 
-    PinConnect = (KSPIN_CONNECT*)(InstanceInfo + 1);
-
-
-    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 = PinId;
-    PinConnect->PinToHandle = ClientInfo->hSysAudio;
-    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;
-
-    /* ros specific pin creation request */
-    InstanceInfo->Property.Id = (ULONG)-1;
-    Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)InstanceInfo, Length, &PinHandle, sizeof(HANDLE), &BytesReturned);
-    if (NT_SUCCESS(Status))
-    {
-        PHANDLE Handels;
-
-        for(Index = 0; Index < ClientInfo->NumPins; Index++)
-        {
-            if (ClientInfo->hPins[Index] == PinHandle)
-            {
-                /* the pin handle has been re-used */
-                DeviceInfo->hDevice = PinHandle;
-                return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
-            }
-
-        }
-
-        Handels = ExAllocatePool(NonPagedPool, sizeof(HANDLE) * (ClientInfo->NumPins+1));
-
-        if (Handels)
-        {
-            if (ClientInfo->NumPins)
-            {
-                RtlMoveMemory(Handels, ClientInfo->hPins, sizeof(HANDLE) * ClientInfo->NumPins);
-                ExFreePool(ClientInfo->hPins);
-            }
-
-            ClientInfo->hPins = Handels;
-            ClientInfo->hPins[ClientInfo->NumPins] = PinHandle;
-            ClientInfo->NumPins++;
-        }
-        DeviceInfo->hDevice = PinHandle;
-    }
-    else
-    {
-        DeviceInfo->hDevice = NULL;
-    }
-
-    return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+    return SetIrpIoStatus(Irp, STATUS_NOT_SUPPORTED, sizeof(WDMAUD_DEVICE_INFO));
 }
 
 NTSTATUS
@@ -278,80 +47,30 @@ WdmAudControlDeviceType(
     IN  PWDMAUD_DEVICE_INFO DeviceInfo,
     IN  PWDMAUD_CLIENT ClientInfo)
 {
-    KSP_PIN Pin;
-    ULONG Count, BytesReturned, Index, SubIndex, Result, NumPins;
-    NTSTATUS Status;
-    KSPIN_COMMUNICATION Communication;
-    KSPIN_DATAFLOW DataFlow;
+    ULONG Result = 0;
+    NTSTATUS Status = STATUS_SUCCESS;
+    PWDMAUD_DEVICE_EXTENSION DeviceExtension;
 
-    if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE)
+    DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+    if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
     {
-        DPRINT1("FIXME: Unsupported device type %x\n", DeviceInfo->DeviceType);
-        return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+        Result = DeviceExtension->MixerInfoCount;
     }
-
-    Pin.Property.Set = KSPROPSETID_Sysaudio;
-    Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
-    Pin.Property.Flags = KSPROPERTY_TYPE_GET;
-
-    Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned);
-    if (!NT_SUCCESS(Status))
+    else if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
     {
-        DPRINT1("KSPROPERTY_SYSAUDIO_DEVICE_COUNT failed with %x\n", Status);
-        return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+        Result = DeviceExtension->WaveOutDeviceCount;
     }
-    Result = 0;
-    /* now enumerate all available filters */
-    for(Index = 0; Index < Count; Index++)
+    else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
     {
-        /* query number of pins */
-        Pin.Reserved = Index; // see sysaudio
-        Pin.Property.Flags = KSPROPERTY_TYPE_GET;
-        Pin.Property.Set = KSPROPSETID_Pin;
-        Pin.Property.Id = KSPROPERTY_PIN_CTYPES;
-        Pin.PinId = 0;
-
-        Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG), &BytesReturned);
-        if (NT_SUCCESS(Status))
-        {
-            /* enumerate now all pins */
-            for(SubIndex = 0; SubIndex < NumPins; SubIndex++)
-            {
-                Pin.PinId = SubIndex;
-                Pin.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
-                Communication = KSPIN_COMMUNICATION_NONE;
-
-                /* get pin communication type */
-                KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned);
-
-                Pin.Property.Id = KSPROPERTY_PIN_DATAFLOW;
-                DataFlow = 0;
-
-                /* get pin dataflow type */
-                KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned);
-
-                if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
-                {
-                    if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_IN)
-                        Result++;
-                }
-                else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
-                {
-                    if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_OUT)
-                        Result++;
-                }
-            }
-        }
+        Result = DeviceExtension->WaveInDeviceCount;
     }
 
+    /* store result count */
+    DeviceInfo->DeviceCount = Result;
 
-    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));
+    DPRINT("WdmAudControlDeviceType Status %x Devices %u\n", Status, DeviceInfo->DeviceCount);
+    return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
 }
 
 NTSTATUS
@@ -367,12 +86,12 @@ WdmAudControlDeviceState(
     ULONG BytesReturned;
     PFILE_OBJECT FileObject;
 
-    //DPRINT1("WdmAudControlDeviceState\n");
+    DPRINT("WdmAudControlDeviceState\n");
 
     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);
+        DPRINT1("Error: invalid device handle provided %p Type %x\n", DeviceInfo->hDevice, DeviceInfo->DeviceType);
         return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
     }
 
@@ -380,203 +99,253 @@ WdmAudControlDeviceState(
     Property.Id = KSPROPERTY_CONNECTION_STATE;
     Property.Flags = KSPROPERTY_TYPE_SET;
 
-    State = DeviceInfo->State;
+    State = DeviceInfo->u.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);
+    DPRINT("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)
+WdmAudCapabilities(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  PIRP Irp,
+    IN  PWDMAUD_DEVICE_INFO DeviceInfo,
+    IN  PWDMAUD_CLIENT ClientInfo)
 {
-    PWRITE_CONTEXT Context = (PWRITE_CONTEXT)Ctx;
+    PWDMAUD_DEVICE_EXTENSION DeviceExtension;
+    NTSTATUS Status = STATUS_UNSUCCESSFUL;
+
+    DPRINT("WdmAudCapabilities entered\n");
 
-    Context->Irp->IoStatus.Information = Context->Length;
-    Context->Irp->IoStatus.Status = Irp->IoStatus.Status;
-    IoCompleteRequest(Context->Irp, IO_SOUND_INCREMENT);
+    DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
-    ExFreePool(Context);
-    return STATUS_SUCCESS;
+    if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
+    {
+        Status = WdmAudMixerCapabilities(DeviceObject, DeviceInfo, ClientInfo, DeviceExtension);
+    }
+    else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
+    {
+        Status = WdmAudWaveCapabilities(DeviceObject, DeviceInfo, ClientInfo, DeviceExtension);
+    }
+
+    return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
 }
 
-ULONG
-CheckFormatSupport(
-    IN PKSDATARANGE_AUDIO DataRangeAudio,
-    ULONG SampleFrequency,
-    ULONG Mono8Bit,
-    ULONG Stereo8Bit,
-    ULONG Mono16Bit,
-    ULONG Stereo16Bit)
+NTSTATUS
+NTAPI
+WdmAudIoctlClose(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  PIRP Irp,
+    IN  PWDMAUD_DEVICE_INFO DeviceInfo,
+    IN  PWDMAUD_CLIENT ClientInfo)
 {
-    ULONG Result = 0;
+    ULONG Index;
 
-    if (DataRangeAudio->MinimumSampleFrequency <= SampleFrequency && DataRangeAudio->MaximumSampleFrequency >= SampleFrequency)
+    for(Index = 0; Index < ClientInfo->NumPins; Index++)
     {
-        if (DataRangeAudio->MinimumBitsPerSample <= 8 && DataRangeAudio->MaximumBitsPerSample >= 8)
+        if (ClientInfo->hPins[Index].Handle == DeviceInfo->hDevice && ClientInfo->hPins[Index].Type != MIXER_DEVICE_TYPE)
         {
-            Result |= Mono8Bit;
-            if (DataRangeAudio->MaximumChannels >= 2)
-            {
-                Result |= Stereo8Bit;
-            }
+            DPRINT1("Closing device %p\n", DeviceInfo->hDevice);
+            ZwClose(DeviceInfo->hDevice);
+            ClientInfo->hPins[Index].Handle = NULL;
+            SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
+            return STATUS_SUCCESS;
         }
-
-        if (DataRangeAudio->MinimumBitsPerSample <= 16 && DataRangeAudio->MaximumBitsPerSample >= 16)
+        else if (ClientInfo->hPins[Index].Handle == DeviceInfo->hDevice && ClientInfo->hPins[Index].Type == MIXER_DEVICE_TYPE)
         {
-            Result |= Mono16Bit;
-            if (DataRangeAudio->MaximumChannels >= 2)
+            if (ClientInfo->hPins[Index].NotifyEvent)
             {
-                Result |= Stereo8Bit;
-            }
+                ObDereferenceObject(ClientInfo->hPins[Index].NotifyEvent);
+                ClientInfo->hPins[Index].NotifyEvent = NULL;
+    }
         }
     }
-    return Result;
 
+    SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, sizeof(WDMAUD_DEVICE_INFO));
+    return STATUS_INVALID_PARAMETER;
 }
 
 NTSTATUS
-WdmAudCapabilities(
+NTAPI
+WdmAudFrameSize(
     IN  PDEVICE_OBJECT DeviceObject,
     IN  PIRP Irp,
     IN  PWDMAUD_DEVICE_INFO DeviceInfo,
     IN  PWDMAUD_CLIENT ClientInfo)
 {
-    NTSTATUS Status = STATUS_UNSUCCESSFUL;
-    KSP_PIN PinProperty;
-    KSCOMPONENTID ComponentId;
-    KSMULTIPLE_ITEM * MultipleItem;
+    PFILE_OBJECT FileObject;
+    KSPROPERTY Property;
     ULONG BytesReturned;
-    PKSDATARANGE_AUDIO DataRangeAudio;
-    PKSDATARANGE DataRange;
-    ULONG Index;
-    ULONG wChannels = 0;
-    ULONG dwFormats = 0;
-    ULONG dwSupport = 0;
-    ULONG FilterId;
-    ULONG PinId;
-
-    DPRINT("WdmAudCapabilities entered\n");
+    KSALLOCATOR_FRAMING Framing;
+    NTSTATUS Status;
 
-    Status = GetFilterIdAndPinId(DeviceObject, DeviceInfo, ClientInfo, &FilterId, &PinId);
+    /* Get sysaudio pin file object */
+    Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
     if (!NT_SUCCESS(Status))
     {
-        DPRINT1("Invalid device index provided %u\n", DeviceInfo->DeviceIndex);
-        return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
+        DPRINT1("Invalid buffer handle %p\n", DeviceInfo->hDevice);
+        return SetIrpIoStatus(Irp, Status, 0);
     }
 
-    PinProperty.PinId = FilterId;
-    PinProperty.Property.Set = KSPROPSETID_Sysaudio;
-    PinProperty.Property.Id = KSPROPERTY_SYSAUDIO_COMPONENT_ID;
-    PinProperty.Property.Flags = KSPROPERTY_TYPE_GET;
-
-    RtlZeroMemory(&ComponentId, sizeof(KSCOMPONENTID));
+    /* Setup get framing request */
+    Property.Id = KSPROPERTY_CONNECTION_ALLOCATORFRAMING;
+    Property.Flags = KSPROPERTY_TYPE_GET;
+    Property.Set = KSPROPSETID_Connection;
 
-    Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)&ComponentId, sizeof(KSCOMPONENTID), &BytesReturned);
+    Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&Framing, sizeof(KSALLOCATOR_FRAMING), &BytesReturned);
+    /* Did we succeed */
     if (NT_SUCCESS(Status))
     {
-        DeviceInfo->u.WaveOutCaps.wMid = ComponentId.Manufacturer.Data1 - 0xd5a47fa7;
-        DeviceInfo->u.WaveOutCaps.vDriverVersion = MAKELONG(ComponentId.Version, ComponentId.Revision);
+        /* Store framesize */
+        DeviceInfo->u.FrameSize = Framing.FrameSize;
     }
 
-    PinProperty.Reserved = DeviceInfo->DeviceIndex;
-    PinProperty.PinId = PinId;
-    PinProperty.Property.Set = KSPROPSETID_Pin;
-    PinProperty.Property.Id = KSPROPERTY_PIN_DATARANGES;
-    PinProperty.Property.Flags = KSPROPERTY_TYPE_GET;
+    /* Release file object */
+    ObDereferenceObject(FileObject);
 
-    BytesReturned = 0;
-    Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)NULL, 0, &BytesReturned);
-    if (Status != STATUS_BUFFER_TOO_SMALL)
-    {
-        return SetIrpIoStatus(Irp, Status, 0);
-    }
+    return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
 
-    MultipleItem = ExAllocatePool(NonPagedPool, BytesReturned);
-    if (!MultipleItem)
-    {
-        /* no memory */
-        return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
-    }
+}
 
-    Status = KsSynchronousIoControlDevice(ClientInfo->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)MultipleItem, BytesReturned, &BytesReturned);
-    if (!NT_SUCCESS(Status))
-    {
-        ExFreePool(MultipleItem);
-        return SetIrpIoStatus(Irp, Status, 0);
-    }
+NTSTATUS
+NTAPI
+WdmAudGetDeviceInterface(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  PIRP Irp,
+    IN  PWDMAUD_DEVICE_INFO DeviceInfo)
+{
+    PWDMAUD_DEVICE_EXTENSION DeviceExtension;
+    NTSTATUS Status;
+    LPWSTR Device;
+    LPWAVE_INFO WaveInfo;
+    ULONG Size, Length;
+
+    /* get device extension */
+    DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
-    DataRange = (PKSDATARANGE) (MultipleItem + 1);
-    for(Index = 0; Index < MultipleItem->Count; Index++)
+    /* get device interface string input length */
+    Size = DeviceInfo->u.Interface.DeviceInterfaceStringSize;
+
+    if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
     {
-        if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
+        /* get wave info */
+        Status = GetWaveInfoByIndexAndType(DeviceObject, DeviceInfo->DeviceIndex, DeviceInfo->DeviceType, &WaveInfo);
+
+        /* check for success */
+        if (!NT_SUCCESS(Status))
         {
-            if (DataRange->FormatSize == sizeof(KSDATARANGE_AUDIO))
-            {
-                DataRangeAudio = (PKSDATARANGE_AUDIO)DataRange;
-                
-                if (IsEqualGUIDAligned(&DataRangeAudio->DataRange.MajorFormat, &KSDATAFORMAT_TYPE_AUDIO) &&
-                    IsEqualGUIDAligned(&DataRangeAudio->DataRange.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM) &&
-                    IsEqualGUIDAligned(&DataRangeAudio->DataRange.Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX))
-                {
-                    DPRINT("Min Sample %u Max Sample %u Min Bits %u Max Bits %u Max Channel %u\n", DataRangeAudio->MinimumSampleFrequency, DataRangeAudio->MaximumSampleFrequency,
-                                                             DataRangeAudio->MinimumBitsPerSample, DataRangeAudio->MaximumBitsPerSample, DataRangeAudio->MaximumChannels);
-
-                    dwFormats |= CheckFormatSupport(DataRangeAudio, 11025, WAVE_FORMAT_1M08, WAVE_FORMAT_1S08, WAVE_FORMAT_1M16, WAVE_FORMAT_1S16);
-                    dwFormats |= CheckFormatSupport(DataRangeAudio, 22050, WAVE_FORMAT_2M08, WAVE_FORMAT_2S08, WAVE_FORMAT_2M16, WAVE_FORMAT_2S16);
-                    dwFormats |= CheckFormatSupport(DataRangeAudio, 44100, WAVE_FORMAT_4M08, WAVE_FORMAT_4S08, WAVE_FORMAT_4M16, WAVE_FORMAT_4S16);
-                    dwFormats |= CheckFormatSupport(DataRangeAudio, 48000, WAVE_FORMAT_48M08, WAVE_FORMAT_48S08, WAVE_FORMAT_48M16, WAVE_FORMAT_48S16);
-                    dwFormats |= CheckFormatSupport(DataRangeAudio, 96000, WAVE_FORMAT_96M08, WAVE_FORMAT_96S08, WAVE_FORMAT_96M16, WAVE_FORMAT_96S16);
-
-
-                    wChannels = DataRangeAudio->MaximumChannels;
-                    dwSupport = WAVECAPS_VOLUME; //FIXME get info from nodes
-                }
-            }
+            /* invalid device id */
+            return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+        }
+
+        Status = GetSysAudioDevicePnpName(DeviceObject, WaveInfo->FilterId, &Device);
+        /* check for success */
+        if (!NT_SUCCESS(Status))
+        {
+            /* invalid device id */
+            return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+        }
+
+        /* calculate length */
+        Length = (wcslen(Device)+1) * sizeof(WCHAR);
+
+        if (!Size)
+        {
+            /* store device interface size */
+            DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
+        }
+        else if (Size < Length)
+        {
+            /* buffer too small */
+            DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
+            return SetIrpIoStatus(Irp, STATUS_BUFFER_OVERFLOW, sizeof(WDMAUD_DEVICE_INFO));
+        }
+        else
+        {
+            //FIXME SEH
+            RtlMoveMemory(DeviceInfo->u.Interface.DeviceInterfaceString, Device, Length);
         }
-        DataRange = (PKSDATARANGE)((PUCHAR)DataRange + DataRange->FormatSize);
+
+        ExFreePool(Device);
+        return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
     }
+    else if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
+    {
+        if (DeviceInfo->DeviceIndex >= DeviceExtension->MixerInfoCount)
+        {
+            /* invalid device id */
+            return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, sizeof(WDMAUD_DEVICE_INFO));
+        }
 
-    DeviceInfo->u.WaveOutCaps.dwFormats = dwFormats;
-    DeviceInfo->u.WaveOutCaps.dwSupport = dwSupport;
-    DeviceInfo->u.WaveOutCaps.wChannels = wChannels;
-    DeviceInfo->u.WaveOutCaps.szPname[0] = L'\0';
+        Status = GetSysAudioDevicePnpName(DeviceObject, DeviceExtension->MixerInfo[DeviceInfo->DeviceIndex].DeviceIndex, &Device);
+        /* check for success */
+        if (!NT_SUCCESS(Status))
+        {
+            /* invalid device id */
+            return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+        }
 
+        /* calculate length */
+        Length = (wcslen(Device)+1) * sizeof(WCHAR);
 
-    ExFreePool(MultipleItem);
-    return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+        if (!Size)
+        {
+            /* store device interface size */
+            DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
+        }
+        else if (Size < Length)
+        {
+            /* buffer too small */
+            DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
+            return SetIrpIoStatus(Irp, STATUS_BUFFER_OVERFLOW, sizeof(WDMAUD_DEVICE_INFO));
+        }
+        else
+        {
+            //FIXME SEH
+            RtlMoveMemory(DeviceInfo->u.Interface.DeviceInterfaceString, Device, Length);
+        }
+
+        ExFreePool(Device);
+        return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
+    }
+
+    return SetIrpIoStatus(Irp, STATUS_INVALID_DEVICE_REQUEST, sizeof(WDMAUD_DEVICE_INFO));
 }
 
 NTSTATUS
 NTAPI
-WdmAudIoctlClose(
+WdmAudResetStream(
     IN  PDEVICE_OBJECT DeviceObject,
     IN  PIRP Irp,
-    IN  PWDMAUD_DEVICE_INFO DeviceInfo,
-    IN  PWDMAUD_CLIENT ClientInfo)
+    IN  PWDMAUD_DEVICE_INFO DeviceInfo)
 {
-    ULONG Index;
+    KSRESET ResetStream;
+    NTSTATUS Status;
+    ULONG BytesReturned;
+    PFILE_OBJECT FileObject;
 
-    for(Index = 0; Index < ClientInfo->NumPins; Index++)
+    DPRINT("WdmAudResetStream\n");
+
+    Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+    if (!NT_SUCCESS(Status))
     {
-        if (ClientInfo->hPins[Index] == DeviceInfo->hDevice)
-        {
-            DPRINT1("Closing device %p\n", DeviceInfo->hDevice);
-            ZwClose(DeviceInfo->hDevice);
-            ClientInfo->hPins[Index] = NULL;
-            SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
-            return STATUS_SUCCESS;
-        }
+        DPRINT1("Error: invalid device handle provided %p Type %x\n", DeviceInfo->hDevice, DeviceInfo->DeviceType);
+        return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
     }
-    SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, sizeof(WDMAUD_DEVICE_INFO));
-    return STATUS_INVALID_PARAMETER;
+
+    ResetStream = DeviceInfo->u.ResetStream;
+    ASSERT(ResetStream == KSRESET_BEGIN || ResetStream == KSRESET_END);
+
+    Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_RESET_STATE, (PVOID)&ResetStream, sizeof(KSRESET), NULL, 0, &BytesReturned);
+
+    ObDereferenceObject(FileObject);
+
+    DPRINT("WdmAudResetStream Status %x\n", Status);
+    return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
 }
 
 NTSTATUS
@@ -631,6 +400,23 @@ WdmAudDeviceControl(
             return WdmAudCapabilities(DeviceObject, Irp, DeviceInfo, ClientInfo);
         case IOCTL_CLOSE_WDMAUD:
             return WdmAudIoctlClose(DeviceObject, Irp, DeviceInfo, ClientInfo);
+        case IOCTL_GETFRAMESIZE:
+            return WdmAudFrameSize(DeviceObject, Irp, DeviceInfo, ClientInfo);
+        case IOCTL_GETLINEINFO:
+            return WdmAudGetLineInfo(DeviceObject, Irp, DeviceInfo, ClientInfo);
+        case IOCTL_GETLINECONTROLS:
+            return WdmAudGetLineControls(DeviceObject, Irp, DeviceInfo, ClientInfo);
+        case IOCTL_SETCONTROLDETAILS:
+            return WdmAudSetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo);
+        case IOCTL_GETCONTROLDETAILS:
+            return WdmAudGetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo);
+        case IOCTL_QUERYDEVICEINTERFACESTRING:
+            return WdmAudGetDeviceInterface(DeviceObject, Irp, DeviceInfo);
+        case IOCTL_GET_MIXER_EVENT:
+            return WdmAudGetMixerEvent(DeviceObject, Irp, DeviceInfo, ClientInfo);
+        case IOCTL_RESET_STREAM:
+            return WdmAudResetStream(DeviceObject, Irp, DeviceInfo);
+        case IOCTL_GETPOS:
         case IOCTL_GETDEVID:
         case IOCTL_GETVOLUME:
         case IOCTL_SETVOLUME:
@@ -642,107 +428,104 @@ WdmAudDeviceControl(
     return SetIrpIoStatus(Irp, STATUS_NOT_IMPLEMENTED, 0);
 }
 
+
 NTSTATUS
 NTAPI
-WdmAudWrite(
+WdmAudReadWrite(
     IN  PDEVICE_OBJECT DeviceObject,
     IN  PIRP Irp)
 {
-    PIO_STACK_LOCATION IoStack;
+    NTSTATUS Status;
     PWDMAUD_DEVICE_INFO DeviceInfo;
-    PWDMAUD_CLIENT ClientInfo;
-    NTSTATUS Status = STATUS_SUCCESS;
-    PUCHAR Buffer;
-    PCONTEXT_WRITE Packet;
     PFILE_OBJECT FileObject;
-    IO_STATUS_BLOCK IoStatusBlock;
+    PIO_STACK_LOCATION IoStack;
+    ULONG Length;
+    PMDL Mdl;
+    BOOLEAN Read = TRUE;
 
+    /* get current irp stack location */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
-    //DPRINT("WdmAudWrite entered\n");
+    /* store the input buffer in UserBuffer - as KsProbeStreamIrp operates on IRP_MJ_DEVICE_CONTROL */
+    Irp->UserBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
 
-    if (IoStack->Parameters.Write.Length < sizeof(WDMAUD_DEVICE_INFO))
-    {
-        /* invalid parameter */
-        DPRINT1("Input buffer too small size %u expected %u\n", IoStack->Parameters.Write.Length, sizeof(WDMAUD_DEVICE_INFO));
-        return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
-    }
+    /* sanity check */
+    ASSERT(Irp->UserBuffer);
 
-    DeviceInfo = (PWDMAUD_DEVICE_INFO)MmGetMdlVirtualAddress(Irp->MdlAddress);
+    /* get the length of the request length */
+    Length = IoStack->Parameters.Write.Length;
 
+    /* store outputbuffer length */
+    IoStack->Parameters.DeviceIoControl.OutputBufferLength = Length;
 
-    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);
-    }
+    /* store mdl address */
+    Mdl = Irp->MdlAddress;
 
+    /* remove mdladdress as KsProbeStreamIrp will interprete it as an already probed audio buffer */
+    Irp->MdlAddress = NULL;
 
-    //DPRINT("DeviceInfo %p %p %p\n", DeviceInfo, Irp->MdlAddress->StartVa, Irp->MdlAddress->MappedSystemVa);
-    if (DeviceInfo->DeviceType < MIN_SOUND_DEVICE_TYPE || DeviceInfo->DeviceType > MAX_SOUND_DEVICE_TYPE)
+    /* check for success */
+
+    if (IoStack->MajorFunction == IRP_MJ_WRITE)
     {
-        /* invalid parameter */
-        DPRINT1("Error: device type not set\n");
-        return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
+        /* probe the write stream irp */
+        Read = FALSE;
+        Status = KsProbeStreamIrp(Irp, KSPROBE_STREAMWRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK, Length);
     }
-
-    if (!IoStack->FileObject)
+    else
     {
-        /* file object parameter */
-        DPRINT1("Error: file object is not attached\n");
-        return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+        /* probe the read stream irp */
+        Status = KsProbeStreamIrp(Irp, KSPROBE_STREAMREAD | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK, Length);
     }
-    ClientInfo = (PWDMAUD_CLIENT)IoStack->FileObject->FsContext;
 
+    /* now free the mdl */
+    IoFreeMdl(Mdl);
 
-    /* setup stream context */
-    Packet = (PCONTEXT_WRITE)ExAllocatePool(NonPagedPool, sizeof(CONTEXT_WRITE));
-    if (!Packet)
+    if (!NT_SUCCESS(Status))
     {
-        /* no memory */
-        return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+        DPRINT1("KsProbeStreamIrp failed with Status %x Cancel %u\n", Status, Irp->Cancel);
+        return SetIrpIoStatus(Irp, Status, 0);
     }
 
-    Packet->Header.FrameExtent = DeviceInfo->BufferSize;
-    Packet->Header.DataUsed = DeviceInfo->BufferSize;
-    Packet->Header.Size = sizeof(KSSTREAM_HEADER);
-    Packet->Header.PresentationTime.Numerator = 1;
-    Packet->Header.PresentationTime.Denominator = 1;
-    Packet->Irp = Irp;
+    /* get device info */
+    DeviceInfo = (PWDMAUD_DEVICE_INFO)Irp->AssociatedIrp.SystemBuffer;
+    ASSERT(DeviceInfo);
 
-    Buffer = ExAllocatePool(NonPagedPool, DeviceInfo->BufferSize);
-    if (!Buffer)
+    /* now get sysaudio file object */
+    Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+    if (!NT_SUCCESS(Status))
     {
-        /* no memory */
-        ExFreePool(Packet);
-        return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+        DPRINT1("Invalid pin handle %p\n", DeviceInfo->hDevice);
+        return SetIrpIoStatus(Irp, Status, 0);
     }
-    Packet->Header.Data = Buffer;
 
-    _SEH2_TRY
+    /* skip current irp stack location */
+    IoSkipCurrentIrpStackLocation(Irp);
+
+    /* get next stack location */
+    IoStack = IoGetNextIrpStackLocation(Irp);
+
+    if (Read)
     {
-        ProbeForRead(DeviceInfo->Buffer, DeviceInfo->BufferSize, TYPE_ALIGNMENT(char));
-        RtlMoveMemory(Buffer, DeviceInfo->Buffer, DeviceInfo->BufferSize);
+        IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_READ_STREAM;
     }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    else
     {
-        /* Exception, get the error code */
-        Status = _SEH2_GetExceptionCode();
+        IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_WRITE_STREAM;
     }
-    _SEH2_END;
 
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("Invalid buffer supplied\n");
-        ExFreePool(Buffer);
-        ExFreePool(Packet);
-        return SetIrpIoStatus(Irp, Status, 0);
-    }
+    /* attach file object */
+    IoStack->FileObject = FileObject;
+    IoStack->Parameters.Write.Length = Length;
+    IoStack->MajorFunction = IRP_MJ_WRITE;
 
-    KsStreamIo(FileObject, NULL, NULL, NULL, NULL, 0, &IoStatusBlock, Packet, sizeof(CONTEXT_WRITE), KSSTREAM_WRITE, KernelMode);
+    /* mark irp as pending */
+//    IoMarkIrpPending(Irp);
+    /* call the driver */
+    Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
 
+    /* dereference file object */
+    ObDereferenceObject(FileObject);
 
-    return IoStatusBlock.Status;
+    return Status;
 }
-