[ros-diffs] [janderwald] 39893: - Implement a fast read / fast write path with KsStreamIo - Fix 2 bugs in KsRegister*Worker code - Implement fast write support for the general purpose dispatcher in portcls - Implement a IIrpQueue object will queue pending irp requests - Refactor IPinWaveCyclic interrupt handling code to work with IIrpQueue - Handle wave out request in IRP_MJ_WRITE and submit them using KsStreamIo -

janderwald at svn.reactos.org janderwald at svn.reactos.org
Fri Mar 6 20:06:22 CET 2009


Author: janderwald
Date: Fri Mar  6 22:06:21 2009
New Revision: 39893

URL: http://svn.reactos.org/svn/reactos?rev=39893&view=rev
Log:
- Implement a fast read / fast write path with KsStreamIo
- Fix 2 bugs in KsRegister*Worker code
- Implement fast write support for the general purpose dispatcher in portcls
- Implement a IIrpQueue object will queue pending irp requests
- Refactor IPinWaveCyclic interrupt handling code to work with IIrpQueue
- Handle wave out request in IRP_MJ_WRITE and submit them using KsStreamIo
- 

Modified:
    trunk/reactos/drivers/ksfilter/ks/irp.c
    trunk/reactos/drivers/ksfilter/ks/worker.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/adapter.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h
    trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild
    trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h
    trunk/reactos/drivers/wdm/audio/drivers/directory.rbuild
    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/wdmaud.h
    trunk/reactos/drivers/wdm/audio/sysaudio/pin.c

Modified: trunk/reactos/drivers/ksfilter/ks/irp.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/irp.c?rev=39893&r1=39892&r2=39893&view=diff
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] Fri Mar  6 22:06:21 2009
@@ -1077,6 +1077,8 @@
     ULONG Code;
     NTSTATUS Status;
     LARGE_INTEGER Offset;
+    PKSIOBJECT_HEADER ObjectHeader;
+
 
     if (Flags == KSSTREAM_READ)
         Code = IRP_MJ_READ;
@@ -1092,6 +1094,30 @@
     if (Event)
     {
         KeResetEvent(Event);
+    }
+
+    //ASSERT(DeviceObject->DeviceType == FILE_DEVICE_KS);
+    ObjectHeader = (PKSIOBJECT_HEADER)FileObject->FsContext;
+    ASSERT(ObjectHeader);
+    if (Code == IRP_MJ_READ)
+    {
+        if (ObjectHeader->DispatchTable.FastRead)
+        {
+            if (ObjectHeader->DispatchTable.FastRead(FileObject, NULL, Length, FALSE, 0, StreamHeaders, IoStatusBlock, DeviceObject))
+            {
+                return STATUS_SUCCESS;
+            }
+        }
+    }
+    else
+    {
+        if (ObjectHeader->DispatchTable.FastWrite)
+        {
+            if (ObjectHeader->DispatchTable.FastWrite(FileObject, NULL, Length, FALSE, 0, StreamHeaders, IoStatusBlock, DeviceObject))
+            {
+                return STATUS_SUCCESS;
+            }
+        }
     }
 
     Offset.QuadPart = 0LL;

Modified: trunk/reactos/drivers/ksfilter/ks/worker.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/worker.c?rev=39893&r1=39892&r2=39893&view=diff
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/worker.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/worker.c [iso-8859-1] Fri Mar  6 22:06:21 2009
@@ -43,7 +43,7 @@
     KsWorker->Counter = 0;
     KsWorker->WorkItemActive = 0;
     KsWorker->WorkItem = NULL;
-    KsWorker->DeleteInProgress = TRUE;
+    KsWorker->DeleteInProgress = FALSE;
     KeInitializeSpinLock(&KsWorker->Lock);
     KeInitializeEvent(&KsWorker->Event, NotificationEvent, FALSE);
 
@@ -181,6 +181,9 @@
     if (!KsWorker->DeleteInProgress)
     {
         ExQueueWorkItem(WorkItem, KsWorker->Type);
+    }
+    else
+    {
         Status = STATUS_UNSUCCESSFUL;
     }
 

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/adapter.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/adapter.c?rev=39893&r1=39892&r2=39893&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/adapter.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/adapter.c [iso-8859-1] Fri Mar  6 22:06:21 2009
@@ -200,7 +200,8 @@
     return status;
 }
 
-NTSTATUS NTAPI
+NTSTATUS
+NTAPI
 PcRegisterSubdevice(
     IN  PDEVICE_OBJECT DeviceObject,
     IN  PWCHAR Name,
@@ -215,16 +216,24 @@
 
     DPRINT1("PcRegisterSubdevice DeviceObject %p Name %S Unknown %p\n", DeviceObject, Name, Unknown);
 
+    /* check if all parameters are valid */
     if (!DeviceObject || !Name || !Unknown)
     {
         DPRINT("PcRegisterSubdevice invalid parameter\n");
         return STATUS_INVALID_PARAMETER;
     }
 
+    /* get device extension */
     DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
     if (!DeviceExt)
+    {
+        /* should not happen */
+        KeBugCheck(0);
         return STATUS_UNSUCCESSFUL;
-
+    }
+
+    /* look up our undocumented interface */
     Status = Unknown->lpVtbl->QueryInterface(Unknown, &IID_ISubdevice, (LPVOID)&SubDevice);
     if (!NT_SUCCESS(Status))
     {

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c?rev=39893&r1=39892&r2=39893&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.c [iso-8859-1] Fri Mar  6 22:06:21 2009
@@ -215,9 +215,12 @@
     PIO_STATUS_BLOCK IoStatus,
     PDEVICE_OBJECT DeviceObject)
 {
+    IIrpTarget * IrpTarget;
     DPRINT1("Dispatch_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject);
 
-    return FALSE;
+    IrpTarget = (IIrpTarget *)FileObject->FsContext2;
+
+    return IrpTarget->lpVtbl->FastWrite(IrpTarget, FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject);
 }
 
 static KSDISPATCH_TABLE DispatchTable =
@@ -244,6 +247,7 @@
     NTSTATUS Status;
     KSOBJECT_HEADER ObjectHeader;
     PKSOBJECT_CREATE_ITEM CreateItem;
+    PIO_STACK_LOCATION IoStack;
 
     CreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM), TAG_PORTCLASS);
     if (!CreateItem)
@@ -251,6 +255,11 @@
 
     CreateItem->Context = (PVOID)Target;
 
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+    ASSERT(IoStack->FileObject);
+
+    IoStack->FileObject->FsContext2 = (PVOID)Target;
+
     Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);
     DPRINT1("KsAllocateObjectHeader result %x\n", Status);
     return Status;

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h?rev=39893&r1=39892&r2=39893&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] Fri Mar  6 22:06:21 2009
@@ -180,6 +180,44 @@
 };
 
 /*****************************************************************************
+ * IIrpQueue
+ *****************************************************************************
+ */
+
+#undef INTERFACE
+#define INTERFACE IIrpQueue
+
+DECLARE_INTERFACE_(IIrpQueue, IUnknown)
+{
+    DEFINE_ABSTRACT_UNKNOWN()
+
+    STDMETHOD_(NTSTATUS, Init)(THIS_
+        IN KSPIN_CONNECT *ConnectDetails,
+        IN PDEVICE_OBJECT DeviceObject);
+
+    STDMETHOD_(NTSTATUS, AddMapping)(THIS_
+        IN PUCHAR Buffer,
+        IN ULONG BufferSize,
+        IN PIRP Irp);
+
+    STDMETHOD_(NTSTATUS, GetMapping)(THIS_
+        OUT PUCHAR * Buffer,
+        OUT PULONG BufferSize);
+
+    STDMETHOD_(VOID, UpdateMapping)(THIS_
+        IN ULONG BytesWritten);
+
+    STDMETHOD_(ULONG, NumMappings)(THIS);
+
+    STDMETHOD_(ULONG, MinMappings)(THIS);
+
+    STDMETHOD_(ULONG, MaxMappings)(THIS);
+
+};
+
+
+
+/*****************************************************************************
  * IKsWorkSink
  *****************************************************************************
  */

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c?rev=39893&r1=39892&r2=39893&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c [iso-8859-1] Fri Mar  6 22:06:21 2009
@@ -1,4 +1,244 @@
-
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS Kernel Streaming
+ * FILE:            drivers/multimedia/portcls/irpstream.c
+ * PURPOSE:         IRP Stream handling
+ * PROGRAMMER:      Johannes Anderwald
+ *
+ * HISTORY:
+ *                  27 Jan 07   Created
+ */
+
+#include "private.h"
+
+typedef struct _IRP_MAPPING_
+{
+    KSSTREAM_HEADER *Header;
+    PIRP Irp;
+    LIST_ENTRY Entry;
+    struct _IRP_MAPPING_ * Next;
+}IRP_MAPPING, *PIRP_MAPPING;
+
+#define MAX_MAPPING (100)
+
+typedef struct
+{
+    IIrpQueueVtbl *lpVtbl;
+
+    LONG ref;
+
+    ULONG CurrentOffset;
+    ULONG NextMapping;
+    LONG NumMappings;
+    IN KSPIN_CONNECT *ConnectDetails;
+
+    PIRP_MAPPING FirstMap;
+    PIRP_MAPPING LastMap;
+}IIrpQueueImpl;
+
+VOID
+NTAPI
+DpcRoutine(
+    IN struct _KDPC  *Dpc,
+    IN PVOID  DeferredContext,
+    IN PVOID  SystemArgument1,
+    IN PVOID  SystemArgument2);
+
+
+NTSTATUS
+NTAPI
+IIrpQueue_fnQueryInterface(
+    IIrpQueue* iface,
+    IN  REFIID refiid,
+    OUT PVOID* Output)
+{
+    IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
+
+    if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
+    {
+        *Output = &This->lpVtbl;
+        _InterlockedIncrement(&This->ref);
+        return STATUS_SUCCESS;
+    }
+    return STATUS_UNSUCCESSFUL;
+}
+
+ULONG
+NTAPI
+IIrpQueue_fnAddRef(
+    IIrpQueue* iface)
+{
+    IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
+
+    return _InterlockedIncrement(&This->ref);
+}
+
+ULONG
+NTAPI
+IIrpQueue_fnRelease(
+    IIrpQueue* iface)
+{
+    IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
+
+    _InterlockedDecrement(&This->ref);
+
+    if (This->ref == 0)
+    {
+        FreeItem(This, TAG_PORTCLASS);
+        return 0;
+    }
+    /* Return new reference count */
+    return This->ref;
+}
+
+
+NTSTATUS
+NTAPI
+IIrpQueue_fnInit(
+    IN IIrpQueue *iface,
+    IN KSPIN_CONNECT *ConnectDetails,
+    IN PDEVICE_OBJECT DeviceObject)
+{
+    IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
+
+    This->ConnectDetails = ConnectDetails;
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+IIrpQueue_fnAddMapping(
+    IN IIrpQueue *iface,
+    IN PUCHAR Buffer,
+    IN ULONG BufferSize,
+    IN PIRP Irp)
+{
+    PIRP_MAPPING Mapping;
+    IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
+
+    Mapping = ExAllocatePool(NonPagedPool, sizeof(IRP_MAPPING));
+    if (!Mapping)
+        return STATUS_UNSUCCESSFUL;
+
+    Mapping->Header = (KSSTREAM_HEADER*)Buffer;
+    Mapping->Irp = Irp;
+
+    if (!This->FirstMap)
+        This->FirstMap = Mapping;
+    else
+        This->LastMap->Next = Mapping;
+
+    This->LastMap = Mapping;
+
+    InterlockedIncrement(&This->NumMappings);
+
+    DPRINT1("IIrpQueue_fnAddMapping NumMappings %u SizeOfMapping %lu\n", This->NumMappings, Mapping->Header->DataUsed);
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+IIrpQueue_fnGetMapping(
+    IN IIrpQueue *iface,
+    OUT PUCHAR * Buffer,
+    OUT PULONG BufferSize)
+{
+    IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
+
+    if (!This->FirstMap)
+        return STATUS_UNSUCCESSFUL;
+
+    *Buffer = (PUCHAR)This->FirstMap->Header->Data + This->CurrentOffset;
+    *BufferSize = This->FirstMap->Header->DataUsed - This->CurrentOffset;
+
+    return STATUS_SUCCESS;
+}
+
+
+
+VOID
+NTAPI
+IIrpQueue_fnUpdateMapping(
+    IN IIrpQueue *iface,
+    IN ULONG BytesWritten)
+{
+    IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
+    PIRP_MAPPING Mapping;
+
+    This->CurrentOffset += BytesWritten;
+
+    if (This->FirstMap->Header->DataUsed <=This->CurrentOffset)
+    {
+        This->CurrentOffset = 0;
+        Mapping = This->FirstMap;
+        This->FirstMap = This->FirstMap->Next;
+
+        //ExFreePool(Mapping->Header->Data);
+        //ExFreePool(Mapping->Header);
+        //IoCompleteRequest(Mapping->Irp, IO_NO_INCREMENT);
+        //ExFreePool(Mapping);
+    }
+}
+
+ULONG
+NTAPI
+IIrpQueue_fnNumMappings(
+    IN IIrpQueue *iface)
+{
+    IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
+
+    return This->NumMappings;
+}
+
+ULONG
+NTAPI
+IIrpQueue_fnMaxMappings(
+    IN IIrpQueue *iface)
+{
+    return MAX_MAPPING;
+}
+
+ULONG
+NTAPI
+IIrpQueue_fnMinMappings(
+    IN IIrpQueue *iface)
+{
+    return MAX_MAPPING / 4;
+}
+
+static IIrpQueueVtbl vt_IIrpQueue =
+{
+    IIrpQueue_fnQueryInterface,
+    IIrpQueue_fnAddRef,
+    IIrpQueue_fnRelease,
+    IIrpQueue_fnInit,
+    IIrpQueue_fnAddMapping,
+    IIrpQueue_fnGetMapping,
+    IIrpQueue_fnUpdateMapping,
+    IIrpQueue_fnNumMappings,
+    IIrpQueue_fnMinMappings,
+    IIrpQueue_fnMaxMappings
+};
+
+
+NTSTATUS
+NTAPI
+NewIrpQueue(
+    IN IIrpQueue **Queue)
+{
+    IIrpQueueImpl *This = AllocateItem(NonPagedPool, sizeof(IIrpQueueImpl), TAG_PORTCLASS);
+    if (!This)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    This->ref = 1;
+    This->lpVtbl = &vt_IIrpQueue;
+
+    *Queue = (IIrpQueue*)This;
+    return STATUS_SUCCESS;
+
+}
 
 NTSTATUS
 NewIrpStreamPhysical(

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=39893&r1=39892&r2=39893&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] Fri Mar  6 22:06:21 2009
@@ -16,19 +16,17 @@
     KSSTATE State;
     PKSDATAFORMAT Format;
 
-    LIST_ENTRY QueueHead;
-    KSPIN_LOCK QueueLock;
-
     PVOID CommonBuffer;
     ULONG CommonBufferSize;
     ULONG CommonBufferOffset;
 
-    PIRP ActiveIrp;
+    IIrpQueue * IrpQueue;
+
     PUCHAR ActiveIrpBuffer;
     ULONG ActiveIrpBufferSize;
     ULONG ActiveIrpOffset;
     ULONG DelayedRequestInProgress;
-
+    ULONG RetryCount;
 
 }IPortPinWaveCyclicImpl;
 
@@ -101,88 +99,72 @@
     IServiceSink* iface)
 {
     ULONG Position;
-    ULONG BufferLength, IrpLength, BytesToCopy;
+    ULONG BufferLength, BytesToCopy;
     NTSTATUS Status;
+    PUCHAR Buffer;
+    ULONG BufferSize;
 
     IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortPinWaveCyclicImpl, lpVtblServiceSink);
 
-    if (This->ActiveIrp && This->ActiveIrpOffset >= This->ActiveIrpBufferSize)
-    {
-        This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_PAUSE);
-        if (KeGetCurrentIrql() > DISPATCH_LEVEL)
+
+    Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer, &BufferSize);
+    if (!NT_SUCCESS(Status))
+    {
+        This->RetryCount++;
+        if (This->RetryCount > 30)
         {
-            This->DelayedRequestInProgress = TRUE;
-            This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, -10000000L);
+            DPRINT1("Stopping\n");
+            This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP);
+            This->RetryCount = 0;
             return;
         }
-        else
+        DPRINT("IServiceSink_fnRequestService> Waiting for mapping\n");
+        This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, -10000000L);
+        return;
+    }
+    This->RetryCount = 0;
+
+    if (KeGetCurrentIrql() == DISPATCH_LEVEL)
+        return;
+
+
+    Status = This->Stream->lpVtbl->GetPosition(This->Stream, &Position);
+    DPRINT("Position %u BufferSize %u ActiveIrpOffset %u\n", Position, This->CommonBufferSize, BufferSize);
+
+
+    if (Position < This->CommonBufferOffset)
+    {
+        BufferLength = This->CommonBufferSize - This->CommonBufferOffset;
+
+        BytesToCopy = min(BufferLength, BufferSize);
+
+        DPRINT("Copying %u\n", BytesToCopy);
+
+        if (BytesToCopy)
         {
-            if (This->ActiveIrp)
-            {
-                This->ActiveIrp->IoStatus.Status = STATUS_SUCCESS;
-                This->ActiveIrp->IoStatus.Information = This->ActiveIrpBufferSize;
-                IoCompleteRequest(This->ActiveIrp, IO_SOUND_INCREMENT);
-                This->ActiveIrp = NULL;
-            }
-
-            Status = IPortWaveCyclic_fnProcessNewIrp(This);
-            if (Status == STATUS_SUCCESS)
-                This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_RUN);
-            else
-                This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, -10000000L);
+            This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel, (PUCHAR)This->CommonBuffer + This->CommonBufferOffset, Buffer, BytesToCopy);
+            This->IrpQueue->lpVtbl->UpdateMapping(This->IrpQueue, BytesToCopy);
+            This->CommonBufferOffset = 0;
+        }
+
+
+        Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer, &BufferSize);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT("IServiceSink_fnRequestService> Waiting for mapping\n");
+            This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, -10000000L);
+            This->RetryCount++;
             return;
         }
-    }
-
-    if (!This->ActiveIrp)
-    {
-        if (KeGetCurrentIrql() > DISPATCH_LEVEL)
-        {
-            This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, -10000000L);
-            return;
-        }
-
-        Status = IPortWaveCyclic_fnProcessNewIrp(This);
-        if (Status == STATUS_SUCCESS)
-            This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_RUN);
-        else
-            This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, -10000000L);
-        return;
-    }
-
-    Status = This->Stream->lpVtbl->GetPosition(This->Stream, &Position);
-    DPRINT("Position %u BufferSize %u ActiveIrpOffset %u\n", Position, This->CommonBufferSize, This->ActiveIrpOffset);
-
-    if (Position < This->CommonBufferOffset)
-    {
-        BufferLength = This->CommonBufferSize - This->CommonBufferOffset;
-        IrpLength = This->ActiveIrpBufferSize - This->ActiveIrpOffset;
-
-        BytesToCopy = min(BufferLength, IrpLength);
-
-        DPRINT("Copying %u Remaining %u\n", BytesToCopy, IrpLength);
+
+        BytesToCopy = min(Position, BufferSize);
+
+        DPRINT("Copying %u\n", BytesToCopy);
 
         if (BytesToCopy)
         {
-            This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel, (PUCHAR)This->CommonBuffer + This->CommonBufferOffset, (PUCHAR)This->ActiveIrpBuffer + This->ActiveIrpOffset, BytesToCopy);
-            This->ActiveIrpOffset += BytesToCopy;
-            This->CommonBufferOffset = 0;
-        }
-        else
-        {
-            This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_PAUSE);
-            return;
-        }
-        BufferLength = Position;
-        IrpLength = This->ActiveIrpBufferSize - This->ActiveIrpOffset;
-        BytesToCopy = min(BufferLength, IrpLength);
-
-        DPRINT("Copying %u Remaining %u\n", BytesToCopy, IrpLength);
-
-        if (BytesToCopy)
-        {
-            This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel, (PUCHAR)(PUCHAR)This->CommonBuffer, (PUCHAR)This->ActiveIrpBuffer + This->ActiveIrpOffset, BytesToCopy);
-            This->ActiveIrpOffset += Position;
+            This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel, (PUCHAR)(PUCHAR)This->CommonBuffer, Buffer, BytesToCopy);
+            This->IrpQueue->lpVtbl->UpdateMapping(This->IrpQueue, BytesToCopy);
             This->CommonBufferOffset = Position;
         }
 
@@ -190,23 +172,16 @@
     else if (Position >= This->CommonBufferOffset)
     {
         BufferLength = Position - This->CommonBufferOffset;
-        IrpLength = This->ActiveIrpBufferSize - This->ActiveIrpOffset;
-
-        BytesToCopy = min(BufferLength, IrpLength);
-        DPRINT("Copying %u Remaining %u\n", BytesToCopy, IrpLength);
-
-        if (!BytesToCopy)
-        {
-            This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, -10000000L);
-            return;
-        }
-
-            This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
+
+        BytesToCopy = min(BufferLength, BufferSize);
+        DPRINT("Copying %u\n", BytesToCopy);
+
+         This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
                                          (PUCHAR)This->CommonBuffer + This->CommonBufferOffset,
-                                         (PUCHAR)This->ActiveIrpBuffer + This->ActiveIrpOffset,
+                                          Buffer,
                                          BytesToCopy);
 
-        This->ActiveIrpOffset += BytesToCopy;
+        This->IrpQueue->lpVtbl->UpdateMapping(This->IrpQueue, BytesToCopy);
         This->CommonBufferOffset = Position;
     }
 
@@ -299,44 +274,6 @@
 
 NTSTATUS
 NTAPI
-IPortWaveCyclic_fnProcessNewIrp(
-    IPortPinWaveCyclicImpl * This)
-{
-    PIO_STACK_LOCATION IoStack;
-    PKSSTREAM_HEADER Header;
-
-    This->ActiveIrp = KsRemoveIrpFromCancelableQueue(&This->QueueHead, &This->QueueLock, KsListEntryTail, KsAcquireAndRemove);
-    if (!This->ActiveIrp)
-    {
-        This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, -10000000L);
-        return STATUS_PENDING;
-    }
-
-    DPRINT("ActiveIrp %p\n", This->ActiveIrp);
-
-    IoStack = IoGetCurrentIrpStackLocation(This->ActiveIrp);
-
-    if (IoStack->Parameters.DeviceIoControl.InputBufferLength != sizeof(KSSTREAM_HEADER))
-    {
-        DPRINT1("Irp has unexpected header\n");
-        IoCompleteRequest(This->ActiveIrp, IO_NO_INCREMENT);
-        This->ActiveIrp = NULL;
-        return STATUS_INVALID_PARAMETER;
-    }
-
-    Header = (PKSSTREAM_HEADER)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
-    DPRINT("Header %p Size %u\n", Header, Header->Size);
-
-
-    This->ActiveIrpOffset = 0;
-    This->ActiveIrpBuffer = Header->Data;
-    This->ActiveIrpBufferSize = Header->DataUsed;
-
-    return STATUS_SUCCESS;
-}
-
-NTSTATUS
-NTAPI
 IPortPinWaveCyclic_HandleKsProperty(
     IN IPortPinWaveCyclic * iface,
     IN PIRP Irp)
@@ -381,28 +318,9 @@
                 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
                 if (This->Stream)
                 {
-                    This->CommonBufferOffset = 0;
-                    This->CommonBufferSize = This->DmaChannel->lpVtbl->AllocatedBufferSize(This->DmaChannel);
-                    This->CommonBuffer = This->DmaChannel->lpVtbl->SystemAddress(This->DmaChannel);
-
-                    This->ActiveIrp = KsRemoveIrpFromCancelableQueue(&This->QueueHead, &This->QueueLock, KsListEntryHead, KsAcquireAndRemove);
-                    if (This->ActiveIrp)
-                    {
-                        Status = IPortWaveCyclic_fnProcessNewIrp(This);
-                        DPRINT1("IPortWaveCyclic_fnProcessNewIrp result %x\n", Status);
-                        if (NT_SUCCESS(Status))
-                        {
-                            //FIXME
-                            // verify offset - resume stream
-                            This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel, This->CommonBuffer, This->ActiveIrpBuffer, This->CommonBufferSize);
-                            This->ActiveIrpOffset += This->CommonBufferSize;
-                        }
-                    }
-
-
                     Status = This->Stream->lpVtbl->SetState(This->Stream, *State);
 
-                    DPRINT1("Setting state %x\n", Status);
+                    DPRINT1("Setting state %u %x\n", *State, Status);
                     if (NT_SUCCESS(Status))
                     {
                         This->State = *State;
@@ -502,25 +420,10 @@
     IN IPortPinWaveCyclic * iface,
     IN PIRP Irp)
 {
-    PIO_STACK_LOCATION IoStack;
     IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
 
-    IoStack = IoGetCurrentIrpStackLocation(Irp);
-
-    DPRINT1("IPortPinWaveCyclic_HandleKsStream entered\n");
-
-    if (!This->Stream)
-    {
-        Irp->IoStatus.Information = 0;
-        Irp->IoStatus.Status = STATUS_SUCCESS;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-        return STATUS_SUCCESS;
-    }
-
-    KsAddIrpToCancelableQueue(&This->QueueHead, &This->QueueLock, Irp, KsListEntryTail, NULL);
-    IoMarkIrpPending(Irp);
-    Irp->IoStatus.Information = 0;
-    Irp->IoStatus.Status = STATUS_PENDING;
+    DPRINT1("IPortPinWaveCyclic_HandleKsStream entered State %u Stream %p\n", This->State, This->Stream);
+    DbgBreakPoint();
 
     return STATUS_PENDING;
 }
@@ -720,7 +623,30 @@
     OUT PIO_STATUS_BLOCK StatusBlock,
     IN PDEVICE_OBJECT DeviceObject)
 {
-    return STATUS_SUCCESS;
+    NTSTATUS Status;
+    PCONTEXT_WRITE Packet;
+    IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
+
+    DPRINT1("IPortPinWaveCyclic_fnFastWrite entered\n");
+
+    Packet = (PCONTEXT_WRITE)Buffer;
+
+
+    Status = This->IrpQueue->lpVtbl->AddMapping(This->IrpQueue, Buffer, Length, Packet->Irp);
+
+    if (!NT_SUCCESS(Status))
+        return FALSE;
+
+    if ((This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue) >  This->IrpQueue->lpVtbl->MinMappings(This->IrpQueue)) && 
+        This->State != KSSTATE_RUN)
+    {
+        /* some should initiate a state request but didnt do it */
+        DPRINT1("Starting stream with %lu mappings\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue));
+        This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_RUN);
+        This->State = KSSTATE_RUN;
+    }
+
+    return TRUE;
 }
 
 /*
@@ -737,6 +663,7 @@
 {
     NTSTATUS Status;
     PKSDATAFORMAT DataFormat;
+    PDEVICE_OBJECT DeviceObject;
     IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
 
     Port->lpVtbl->AddRef(Port);
@@ -746,8 +673,15 @@
     This->Filter = Filter;
     This->KsPinDescriptor = KsPinDescriptor;
     This->Miniport = GetWaveCyclicMiniport(Port);
-    KeInitializeSpinLock(&This->QueueLock);
-    InitializeListHead(&This->QueueHead);
+
+    DeviceObject = GetDeviceObject(Port);
+
+
+    Status = NewIrpQueue(&This->IrpQueue);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    Status = This->IrpQueue->lpVtbl->Init(This->IrpQueue, ConnectDetails, DeviceObject);
 
     DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1);
 
@@ -784,6 +718,10 @@
     This->ServiceGroup->lpVtbl->SupportDelayedService(This->ServiceGroup);
 
     This->State = KSSTATE_STOP;
+    This->CommonBufferOffset = 0;
+    This->CommonBufferSize = This->DmaChannel->lpVtbl->AllocatedBufferSize(This->DmaChannel);
+    This->CommonBuffer = This->DmaChannel->lpVtbl->SystemAddress(This->DmaChannel);
+
 
     return STATUS_SUCCESS;
 }

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c?rev=39893&r1=39892&r2=39893&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c [iso-8859-1] Fri Mar  6 22:06:21 2009
@@ -718,6 +718,14 @@
     return This->pMiniport;
 }
 
+PDEVICE_OBJECT
+GetDeviceObject(
+    PPORTWAVECYCLIC iface)
+{
+    IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl *)iface;
+    return This->pDeviceObject;
+}
+
 //---------------------------------------------------------------
 // IPortWaveCyclic constructor
 //

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild?rev=39893&r1=39892&r2=39893&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild [iso-8859-1] Fri Mar  6 22:06:21 2009
@@ -20,6 +20,7 @@
 	<file>filter_wavecyclic.c</file>
 	<file>guids.c</file>
 	<file>irp.c</file>
+	<file>irpstream.c</file>
 	<file>interrupt.c</file>
 	<file>drm.c</file>
 	<file>stubs.c</file>

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h?rev=39893&r1=39892&r2=39893&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] Fri Mar  6 22:06:21 2009
@@ -112,6 +112,11 @@
 NTSTATUS StringFromCLSID(
     const CLSID *id,
     LPWSTR idstr);
+
+NTSTATUS
+NTAPI
+NewIrpQueue(
+    IN IIrpQueue **Queue);
 
 
 typedef struct
@@ -162,6 +167,12 @@
 
 } PCLASS_DEVICE_EXTENSION, *PPCLASS_DEVICE_EXTENSION;
 
+
+typedef struct
+{
+    KSSTREAM_HEADER Header;
+    PIRP Irp;
+}CONTEXT_WRITE, *PCONTEXT_WRITE;
 
 NTSTATUS
 NTAPI
@@ -226,5 +237,8 @@
     IN PIRP Irp,
     IN PSUBDEVICE_DESCRIPTOR Descriptor);
 
+PDEVICE_OBJECT
+GetDeviceObject(
+    IPortWaveCyclic* iface);
 
 #endif

Modified: trunk/reactos/drivers/wdm/audio/drivers/directory.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/drivers/directory.rbuild?rev=39893&r1=39892&r2=39893&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/drivers/directory.rbuild [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/drivers/directory.rbuild [iso-8859-1] Fri Mar  6 22:06:21 2009
@@ -4,6 +4,10 @@
 	<directory name="mpu401">
 		<xi:include href="mpu401/mpu401.rbuild" />
 	</directory>
+	<directory name="CMIDriver">
+		<xi:include href="CMIDriver/cmidriver.rbuild" />
+	</directory>
+
 	<!--directory name="sb16">
 		<xi:include href="sb16/sb16.rbuild" />
 	</directory-->

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=39893&r1=39892&r2=39893&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] Fri Mar  6 22:06:21 2009
@@ -330,8 +330,8 @@
                 }
             }
         }
-		else
-			DPRINT1("KSPROPERTY_PIN_CTYPES index %u failed with %x\n", Index, Status);
+        else
+            DPRINT1("KSPROPERTY_PIN_CTYPES index %u failed with %x\n", Index, Status);
     }
 
 
@@ -357,6 +357,8 @@
     ULONG BytesReturned;
     PFILE_OBJECT FileObject;
 
+    DPRINT1("WdmAudControlDeviceState\n");
+
     Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
     if (!NT_SUCCESS(Status))
     {
@@ -393,90 +395,6 @@
 
     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);
-    ExFreePool(Buffer);
-
-    return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
 }
 
 ULONG
@@ -700,8 +618,6 @@
             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_GETCAPABILITIES:
             return WdmAudCapabilities(DeviceObject, Irp, DeviceInfo, ClientInfo);
         case IOCTL_CLOSE_WDMAUD:
@@ -716,3 +632,112 @@
 
     return SetIrpIoStatus(Irp, STATUS_NOT_IMPLEMENTED, 0);
 }
+
+NTSTATUS
+NTAPI
+WdmAudWrite(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  PIRP Irp)
+{
+    PIO_STACK_LOCATION IoStack;
+    PWDMAUD_DEVICE_INFO DeviceInfo;
+    PWDMAUD_CLIENT ClientInfo;
+    NTSTATUS Status = STATUS_SUCCESS;
+    PUCHAR Buffer;
+    PCONTEXT_WRITE Packet;
+    PFILE_OBJECT FileObject;
+    IO_STATUS_BLOCK IoStatusBlock;
+
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT1("WdmAudWrite entered\n");
+
+    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);
+    }
+
+    DeviceInfo = (PWDMAUD_DEVICE_INFO)MmGetMdlVirtualAddress(Irp->MdlAddress);
+
+
+    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);
+    }
+
+
+    DPRINT1("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)
+    {
+        /* 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;
+
+
+    /* setup stream context */
+    Packet = (PCONTEXT_WRITE)ExAllocatePool(NonPagedPool, sizeof(CONTEXT_WRITE));
+    if (!Packet)
+    {
+        /* no memory */
+        return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 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;
+
+    Buffer = ExAllocatePool(NonPagedPool, DeviceInfo->BufferSize);
+    if (!Buffer)
+    {
+        /* no memory */
+        ExFreePool(Packet);
+        return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
+    }
+    Packet->Header.Data = Buffer;
+
+    _SEH2_TRY
+    {
+        ProbeForRead(DeviceInfo->Buffer, DeviceInfo->BufferSize, TYPE_ALIGNMENT(char));
+        RtlMoveMemory(Buffer, DeviceInfo->Buffer, DeviceInfo->BufferSize);
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        /* Exception, get the error code */
+        Status = _SEH2_GetExceptionCode();
+    }
+    _SEH2_END;
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Invalid buffer supplied\n");
+        ExFreePool(Buffer);
+        ExFreePool(Packet);
+        return SetIrpIoStatus(Irp, Status, 0);
+    }
+
+    KsStreamIo(FileObject, NULL, NULL, NULL, NULL, 0, &IoStatusBlock, Packet, sizeof(CONTEXT_WRITE), KSSTREAM_WRITE, KernelMode);
+
+    Irp->IoStatus.Status = STATUS_PENDING;
+    Irp->IoStatus.Information = 0;
+    IoMarkIrpPending(Irp);
+    return STATUS_PENDING;
+
+    //return SetIrpIoStatus(Irp, STATUS_SUCCESS, 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=39893&r1=39892&r2=39893&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] Fri Mar  6 22:06:21 2009
@@ -247,6 +247,7 @@
     Driver->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = KsDefaultForwardIrp; 
     Driver->MajorFunction[IRP_MJ_CLEANUP] = WdmAudCleanup;
     Driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = WdmAudDeviceControl;
+    Driver->MajorFunction[IRP_MJ_WRITE] = WdmAudWrite;
     Driver->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower;
 
     return WdmAudInstallDevice(Driver);

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=39893&r1=39892&r2=39893&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] Fri Mar  6 22:06:21 2009
@@ -43,6 +43,13 @@
 
 typedef struct
 {
+    KSSTREAM_HEADER Header;
+    PIRP Irp;
+}CONTEXT_WRITE, *PCONTEXT_WRITE;
+
+
+typedef struct
+{
     PIRP Irp;
     IO_STATUS_BLOCK StatusBlock;
     ULONG Length;
@@ -70,4 +77,11 @@
     IN  PDEVICE_OBJECT DeviceObject,
     IN  PIRP Irp);
 
+NTSTATUS
+NTAPI
+WdmAudWrite(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  PIRP Irp);
+
+
 #endif

Modified: trunk/reactos/drivers/wdm/audio/sysaudio/pin.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/pin.c?rev=39893&r1=39892&r2=39893&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/pin.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/pin.c [iso-8859-1] Fri Mar  6 22:06:21 2009
@@ -97,10 +97,10 @@
     ASSERT(Context);
 
     Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IOCTL_KS_WRITE_STREAM,
-                                          IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
-                                          IoStack->Parameters.DeviceIoControl.InputBufferLength,
-                                          Irp->UserBuffer,
-                                          IoStack->Parameters.DeviceIoControl.OutputBufferLength,
+                                          MmGetMdlVirtualAddress(Irp->MdlAddress),
+                                          IoStack->Parameters.Write.Length,
+                                          NULL,
+                                          0,
                                           &BytesReturned);
 
     Irp->IoStatus.Information = BytesReturned;
@@ -216,9 +216,16 @@
     PIO_STATUS_BLOCK IoStatus,
     PDEVICE_OBJECT DeviceObject)
 {
+    PDISPATCH_CONTEXT Context;
+    NTSTATUS Status;
     DPRINT1("Pin_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject);
 
-    return FALSE;
+    Context = (PDISPATCH_CONTEXT)FileObject->FsContext2;
+    Status = KsStreamIo(Context->FileObject, NULL, NULL, NULL, NULL, 0, IoStatus, Buffer, Length, KSSTREAM_WRITE, KernelMode);
+    if (Status == STATUS_SUCCESS)
+        return TRUE;
+    else
+        return FALSE;
 }
 
 static KSDISPATCH_TABLE PinTable =



More information about the Ros-diffs mailing list