[PORTCLS]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Mon, 1 Nov 2010 22:21:24 +0000 (22:21 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Mon, 1 Nov 2010 22:21:24 +0000 (22:21 +0000)
- Portcls does not need to set the size of the audio buffer for completed irps. This is done in a completion callback in wdmaud. Verified with WinXP portcls
[WDMAUD_KERNEL]
- Free allocated mdls in the io completion routine. Also free the associated stream header.
[KS]
- Replace all ms portcls hacks by one.
- MS Portcls is now working in ReactOS (which is nice for testing audio related bugs)

svn path=/trunk/; revision=49417

reactos/drivers/ksfilter/ks/irp.c
reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp
reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp
reactos/drivers/wdm/audio/legacy/wdmaud/control.c
reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h

index 5ff56c9..192aae5 100644 (file)
@@ -898,10 +898,6 @@ ProbeMdl:
             goto ProbeMdl;
     }
 
-#if 0
-    // HACK for MS PORTCLS
-       HeaderSize = Length;
-#endif
     /* probe user mode buffers */
     if (Length && ( (!HeaderSize) || (Length % HeaderSize == 0) || ((ProbeFlags & KSPROBE_ALLOWFORMATCHANGE) && (Length == sizeof(KSSTREAM_HEADER))) ) )
     {
@@ -1370,7 +1366,7 @@ KsRemoveIrpFromCancelableQueue(
     PLIST_ENTRY CurEntry;
     KIRQL OldIrql;
 
-    //DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead, SpinLock, ListLocation, RemovalOperation);
+    DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead, SpinLock, ListLocation, RemovalOperation);
 
     /* check parameters */
     if (!QueueHead || !SpinLock)
@@ -1629,19 +1625,32 @@ KsAddIrpToCancelableQueue(
     PIO_STACK_LOCATION IoStack;
     KIRQL OldLevel;
 
-    DPRINT("KsAddIrpToCancelableQueue QueueHead %p SpinLock %p Irp %p ListLocation %x DriverCancel %p\n", QueueHead, SpinLock, Irp, ListLocation, DriverCancel);
     /* check for required parameters */
     if (!QueueHead || !SpinLock || !Irp)
         return;
 
+    /* get current irp stack */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("KsAddIrpToCancelableQueue QueueHead %p SpinLock %p Irp %p ListLocation %x DriverCancel %p\n", QueueHead, SpinLock, Irp, ListLocation, DriverCancel);
+
+    // HACK for ms portcls
+    if (IoStack->MajorFunction == IRP_MJ_CREATE)
+    {
+        // complete the request
+        Irp->IoStatus.Status = STATUS_SUCCESS;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+        return;
+    }
+
+
     if (!DriverCancel)
     {
         /* default to KsCancelRoutine */
         DriverCancel = KsCancelRoutine;
     }
 
-    /* get current irp stack */
-    IoStack = IoGetCurrentIrpStackLocation(Irp);
 
     /* acquire spinlock */
     KeAcquireSpinLock(SpinLock, &OldLevel);
@@ -1973,12 +1982,6 @@ KsSetMajorFunctionHandler(
     IN  ULONG MajorFunction)
 {
     DPRINT("KsSetMajorFunctionHandler Function %x\n", MajorFunction);
-#if 1
-    // HACK
-    // for MS PORTCLS
-    //
-    DriverObject->MajorFunction[IRP_MJ_CREATE] = KspCreate;
-#endif
 
     switch ( MajorFunction )
     {
@@ -2016,7 +2019,7 @@ KsDispatchIrp(
     PKSIDEVICE_HEADER DeviceHeader;
     PDEVICE_EXTENSION DeviceExtension;
 
-    //DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject, Irp);
+    DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject, Irp);
 
     /* get device extension */
     DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
index af4b0c1..30d7856 100644 (file)
@@ -232,21 +232,21 @@ CInterruptSync::Connect()
     if (IsListEmpty(&m_ServiceRoutines))
         return STATUS_UNSUCCESSFUL;
 
-    DPRINT("Vector %u Level %u Flags %x Affinity %x\n", Descriptor->u.Interrupt.Vector, Descriptor->u.Interrupt.Level, Descriptor->Flags, Descriptor->u.Interrupt.Affinity);
+    DPRINT1("Vector %u Level %u Flags %x Affinity %x\n", Descriptor->u.Interrupt.Vector, Descriptor->u.Interrupt.Level, Descriptor->Flags, Descriptor->u.Interrupt.Affinity);
 
     Status = IoConnectInterrupt(&m_Interrupt,
                                 IInterruptServiceRoutine,
                                 (PVOID)this,
-                                &m_Lock,
+                                NULL, //&m_Lock,
                                 Descriptor->u.Interrupt.Vector,
                                 (KIRQL)Descriptor->u.Interrupt.Level,
                                 (KIRQL)Descriptor->u.Interrupt.Level,
                                 (KINTERRUPT_MODE)(Descriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED),
-                                (Descriptor->Flags != CM_RESOURCE_INTERRUPT_LATCHED),
+                                (Descriptor->ShareDisposition != CmResourceShareDeviceExclusive),
                                 Descriptor->u.Interrupt.Affinity,
                                 FALSE);
 
-    DPRINT("CInterruptSync::Connect result %x\n", Status);
+    DPRINT1("CInterruptSync::Connect result %x\n", Status);
     return Status;
 }
 
index fabf862..628ea73 100644 (file)
@@ -293,7 +293,6 @@ CIrpQueue::UpdateMapping(
 {
     PKSSTREAM_HEADER StreamHeader;
     ULONG Size, NumData, Index;
-    //PMDL CurMdl, NextMdl;
 
     if (!m_Irp)
     {
@@ -340,8 +339,7 @@ CIrpQueue::UpdateMapping(
             return;
         }
 
-       // irp has been processed completly
-
+        // irp has been processed completly
         NumData = 0;
         if (m_Irp->RequestorMode == KernelMode)
             StreamHeader = (PKSSTREAM_HEADER)m_Irp->UserBuffer;
@@ -385,44 +383,10 @@ CIrpQueue::UpdateMapping(
             // done
             return;
         }
-#if 0
-        // now free allocated mdls
-        CurMdl = m_Irp->MdlAddress;
-        for(Index = 0; Index < STREAMHEADER_COUNT(m_Irp); Index++)
-        {
-            // sanity check
-            ASSERT(CurMdl);
-
-            // get next mdl
-            NextMdl = CurMdl->Next;
-
-            // check if mdl is locked
-            if (CurMdl->MdlFlags & MDL_PAGES_LOCKED)
-            {
-                // unlock pages
-                MmUnlockPages(CurMdl);
-            }
-
-            // free mdl
-            IoFreeMdl(CurMdl);
-
-            // proceed to next mdl
-            CurMdl = NextMdl;
-        }
-
-        // all mdls have been freed now
-        m_Irp->MdlAddress = NULL;
-
-        // free allocated KSSTREAM_HEADER
-        ExFreePool(m_Irp->AssociatedIrp.SystemBuffer);
-
-        // is this really needed?
-        m_Irp->AssociatedIrp.SystemBuffer = NULL;
-#endif
 
         // store operation status
         m_Irp->IoStatus.Status = STATUS_SUCCESS;
-        m_Irp->IoStatus.Information = NumData;
+        m_Irp->IoStatus.Information = 0;
 
         // complete the request
         IoCompleteRequest(m_Irp, IO_SOUND_INCREMENT);
index cc4824e..ee5d03f 100644 (file)
@@ -384,6 +384,91 @@ WdmAudDeviceControl(
     return SetIrpIoStatus(Irp, STATUS_NOT_IMPLEMENTED, 0);
 }
 
+NTSTATUS
+NTAPI
+IoCompletion (
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp,
+    PVOID Ctx)
+{
+    PKSSTREAM_HEADER Header;
+    ULONG Length = 0;
+    PMDL Mdl, NextMdl;
+    PWDMAUD_COMPLETION_CONTEXT Context = (PWDMAUD_COMPLETION_CONTEXT)Ctx;
+
+    /* get stream header */
+    Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer;
+
+    /* sanity check */
+    ASSERT(Header);
+
+    /* iterate through all stream headers and collect size */
+    do
+    {
+        if (Context->Function == IOCTL_KS_READ_STREAM)
+        {
+            /* length is stored in DataUsed */
+            Length += Header->DataUsed;
+        }
+        else
+        {
+            /* length stored in frameextend */
+            Length += Header->FrameExtent;
+        }
+
+        /* subtract size */
+        Context->Length -= Header->Size;
+
+        /* move to next stream header */
+        Header = (PKSSTREAM_HEADER)((ULONG_PTR)Header + Header->Size);
+
+    }while(Context->Length);
+
+    /* time to free all allocated mdls */
+    Mdl = Irp->MdlAddress;
+
+    while(Mdl)
+    {
+        /* get next mdl */
+        NextMdl = Mdl->Next;
+
+        /* unlock pages */
+        MmUnlockPages(Mdl);
+
+        /* grab next mdl */
+        Mdl = NextMdl;
+    }
+
+    /* clear mdl list */
+    Irp->MdlAddress = NULL;
+
+   /* check if mdl is locked */
+    if (Context->Mdl->MdlFlags & MDL_PAGES_LOCKED)
+    {
+        /* unlock pages */
+        MmUnlockPages(Context->Mdl);
+    }
+
+    /* now free the mdl */
+    IoFreeMdl(Context->Mdl);
+
+    /* now free the stream header */
+    ExFreePool(Irp->AssociatedIrp.SystemBuffer);
+
+    DPRINT("IoCompletion Irp %p IoStatus %lx Information %lx Length %lu\n", Irp, Irp->IoStatus.Status, Irp->IoStatus.Information, Length);
+
+    if (Irp->IoStatus.Status == STATUS_SUCCESS)
+    {
+        /* store the length */
+        Irp->IoStatus.Information = Length;
+    }
+
+    /* free context */
+    FreeItem(Context);
+
+    return STATUS_SUCCESS;
+}
+
 
 NTSTATUS
 NTAPI
@@ -398,6 +483,20 @@ WdmAudReadWrite(
     ULONG Length;
     PMDL Mdl;
     BOOLEAN Read = TRUE;
+    PWDMAUD_COMPLETION_CONTEXT Context;
+
+    /* allocate completion context */
+    Context = AllocateItem(NonPagedPool, sizeof(WDMAUD_COMPLETION_CONTEXT));
+
+    if (!Context)
+    {
+        /* not enough memory */
+        Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+        /* done */
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
 
     /* get current irp stack location */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -414,6 +513,11 @@ WdmAudReadWrite(
     /* store outputbuffer length */
     IoStack->Parameters.DeviceIoControl.OutputBufferLength = Length;
 
+    /* setup context */
+    Context->Length = Length;
+    Context->Function = (IoStack->MajorFunction == IRP_MJ_WRITE ? IOCTL_KS_WRITE_STREAM : IOCTL_KS_READ_STREAM);
+    Context->Mdl = Irp->MdlAddress;
+
     /* store mdl address */
     Mdl = Irp->MdlAddress;
 
@@ -441,16 +545,6 @@ WdmAudReadWrite(
         return SetIrpIoStatus(Irp, Status, 0);
     }
 
-    /* check if mdl is locked */
-    if (Mdl->MdlFlags & MDL_PAGES_LOCKED)
-    {
-        /* unlock pages */
-        MmUnlockPages(Mdl);
-    }
-
-    /* now free the mdl */
-    IoFreeMdl(Mdl);
-
     /* get device info */
     DeviceInfo = (PWDMAUD_DEVICE_INFO)Irp->AssociatedIrp.SystemBuffer;
     ASSERT(DeviceInfo);
@@ -483,6 +577,9 @@ WdmAudReadWrite(
     IoStack->Parameters.Write.Length = Length;
     IoStack->MajorFunction = IRP_MJ_WRITE;
 
+    IoSetCompletionRoutine(Irp, IoCompletion, (PVOID)Context, TRUE, TRUE, TRUE);
+
+
     /* mark irp as pending */
 //    IoMarkIrpPending(Irp);
     /* call the driver */
index e29377a..002cf8d 100644 (file)
 
 #include "interface.h"
 
+typedef struct
+{
+    PMDL Mdl;
+    ULONG Length;
+    ULONG Function;
+}WDMAUD_COMPLETION_CONTEXT, *PWDMAUD_COMPLETION_CONTEXT;
+
+
 typedef struct
 {
     HANDLE Handle;