[KS]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Wed, 4 Nov 2009 01:54:19 +0000 (01:54 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Wed, 4 Nov 2009 01:54:19 +0000 (01:54 +0000)
- Fix a bug in KsCancelIo which accessed already freed memory
[PORTCLS]
- Cancel all audio stream irps when the it is used in looped stream mode. Fixes re-opening of playback / capture devices in DSound.
- Remove dead code

svn path=/trunk/; revision=43945

reactos/drivers/ksfilter/ks/irp.c
reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp
reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp
reactos/drivers/wdm/audio/backpln/portcls/port_topology.cpp

index 5a1fb5b..4fdebe9 100644 (file)
@@ -1240,6 +1240,7 @@ KsCancelIo(
     PDRIVER_CANCEL OldDriverCancel;
     PIO_STACK_LOCATION IoStack;
     PLIST_ENTRY Entry;
+    PLIST_ENTRY NextEntry;
     PIRP Irp;
     KIRQL OldLevel;
 
@@ -1253,6 +1254,9 @@ KsCancelIo(
         /* get irp offset */
         Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
 
+        /* get next entry */
+        NextEntry = Entry->Flink;
+
         /* set cancelled bit */
         Irp->Cancel = TRUE;
 
@@ -1275,8 +1279,9 @@ KsCancelIo(
             /* re-acquire spinlock */
             KeAcquireSpinLock(SpinLock, &OldLevel);
         }
+
         /* move on to next entry */
-        Entry = Entry->Flink;
+        Entry = NextEntry;
     }
 
     /* the irp has already been canceled */
@@ -1785,7 +1790,7 @@ KspCreate(
     PKSIOBJECT_HEADER ObjectHeader;
     NTSTATUS Status;
 
-    DPRINT("KS / CREATE\n");
+    DPRINT1("KS / CREATE\n");
     /* get current stack location */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
     /* get device extension */
@@ -1838,7 +1843,6 @@ KspCreate(
         return Status;
     }
 
-
     Irp->IoStatus.Information = 0;
     /* set return status */
     Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
index e699964..f201db2 100644 (file)
@@ -441,8 +441,20 @@ BOOL
 NTAPI
 CIrpQueue::CancelBuffers()
 {
+    // is there an active irp
+    if (m_Irp)
+    {
+        // re-insert it to cancelable queue
+        KsAddIrpToCancelableQueue(&m_IrpList, &m_IrpListLock, m_Irp, KsListEntryTail, NULL);
+        //set it to zero
+        m_Irp = NULL;
+    }
 
+    // cancel all irps
+    KsCancelIo(&m_IrpList, &m_IrpListLock);
+    // reset stream start flag
     m_StartStream = FALSE;
+    // done
     return TRUE;
 }
 
index e4b4aaf..38a6ae9 100644 (file)
@@ -268,7 +268,14 @@ PinWaveCyclicState(
         {
             // store new state
             Pin->m_State = *State;
+
+            if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING && Pin->m_State == KSSTATE_STOP)
+            {
+                /* FIXME complete pending irps with successfull state */
+                Pin->m_IrpQueue->CancelBuffers();
+            }
         }
+
         // store result
         Irp->IoStatus.Information = sizeof(KSSTATE);
         return Status;
@@ -905,7 +912,8 @@ CPortPinWaveCyclic::Init(
     }
 #endif
 
-    DPRINT("CPortPinWaveCyclic::Init Status %x\n", Status);
+    DPRINT("CPortPinWaveCyclic::Init Status %x PinId %u Capture %u\n", Status, ConnectDetails->PinId, Capture);
+    DPRINT("Bits %u Samples %u Channels %u Tag %u FrameSize %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.wBitsPerSample, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.nSamplesPerSec, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.nChannels, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.wFormatTag, m_FrameSize);
 
     if (!NT_SUCCESS(Status))
         return Status;
index 658876a..2c80a43 100644 (file)
@@ -55,13 +55,6 @@ protected:
 
 };
 
-typedef struct
-{
-    PIRP Irp;
-    IIrpTarget *Filter;
-    PIO_WORKITEM WorkItem;
-}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT;
-
 static GUID InterfaceGuids[2] = 
 {
     {
@@ -448,57 +441,16 @@ CPortTopology::PinCount(
 }
 
 
-VOID
-NTAPI
-CreatePinWorkerRoutine(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PVOID  Context)
-{
-    NTSTATUS Status;
-    IIrpTarget *Pin;
-    PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context;
-
-    DPRINT("CreatePinWorkerRoutine called\n");
-    // create the pin
-    Status = WorkerContext->Filter->NewIrpTarget(&Pin,
-                                                 KSSTRING_Pin,
-                                                 NULL,
-                                                 NonPagedPool,
-                                                 DeviceObject,
-                                                 WorkerContext->Irp,
-                                                 NULL);
-
-    DPRINT("CreatePinWorkerRoutine Status %x\n", Status);
-
-    if (NT_SUCCESS(Status))
-    {
-        // create the dispatch object
-        // FIXME need create item for clock
-        Status = NewDispatchObject(WorkerContext->Irp, Pin, 0, NULL);
-        DPRINT("Pin %p\n", Pin);
-    }
-
-    DPRINT("CreatePinWorkerRoutine completing irp %p\n", WorkerContext->Irp);
-    // save status in irp
-    WorkerContext->Irp->IoStatus.Status = Status;
-    WorkerContext->Irp->IoStatus.Information = 0;
-    // complete the request
-    IoCompleteRequest(WorkerContext->Irp, IO_SOUND_INCREMENT);
-    // free allocated work item
-    IoFreeWorkItem(WorkerContext->WorkItem);
-    // free context
-    FreeItem(WorkerContext, TAG_PORTCLASS);
-}
-
 NTSTATUS
 NTAPI
 PcCreatePinDispatch(
     IN  PDEVICE_OBJECT DeviceObject,
     IN  PIRP Irp)
 {
+    NTSTATUS Status;
     IIrpTarget *Filter;
+    IIrpTarget *Pin;
     PKSOBJECT_CREATE_ITEM CreateItem;
-    PPIN_WORKER_CONTEXT Context;
 
     // access the create item
     CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
@@ -511,6 +463,7 @@ PcCreatePinDispatch(
 
     // sanity checks
     PC_ASSERT(Filter != NULL);
+    PC_ASSERT_IRQL(PASSIVE_LEVEL);
 
 
 #if KS_IMPLEMENTED
@@ -524,45 +477,33 @@ PcCreatePinDispatch(
     }
 #endif
 
-     // new pins are instantiated at passive level,
-     // so allocate a work item and context for it 
-     
-
-       Context = (PPIN_WORKER_CONTEXT)AllocateItem(NonPagedPool, sizeof(PIN_WORKER_CONTEXT), TAG_PORTCLASS);
-     if (!Context)
-     {
-         DPRINT("Failed to allocate worker context\n");
-         Irp->IoStatus.Information = 0;
-         Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
-         IoCompleteRequest(Irp, IO_NO_INCREMENT);
-         return STATUS_INSUFFICIENT_RESOURCES;
-    }
+    Status = Filter->NewIrpTarget(&Pin,
+                                  KSSTRING_Pin,
+                                  NULL,
+                                  NonPagedPool,
+                                  DeviceObject,
+                                  Irp,
+                                  NULL);
+
+    DPRINT("PcCreatePinDispatch Status %x\n", Status);
 
-    // allocate work item
-    Context->WorkItem = IoAllocateWorkItem(DeviceObject);
-    if (!Context->WorkItem)
+    if (NT_SUCCESS(Status))
     {
-        DPRINT("Failed to allocate workitem\n");
-        FreeItem(Context, TAG_PORTCLASS);
-        Irp->IoStatus.Information = 0;
-        Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-        return STATUS_INSUFFICIENT_RESOURCES;
+        // create the dispatch object
+        // FIXME need create item for clock
+        Status = NewDispatchObject(Irp, Pin, 0, NULL);
+        DPRINT("Pin %p\n", Pin);
     }
 
-    Context->Filter = Filter;
-    Context->Irp = Irp;
-
-    DPRINT("Queueing IRP %p Irql %u\n", Irp, KeGetCurrentIrql());
+    DPRINT("CreatePinWorkerRoutine completing irp %p\n", Irp);
+    // save status in irp
+    Irp->IoStatus.Status = Status;
     Irp->IoStatus.Information = 0;
-    Irp->IoStatus.Status = STATUS_PENDING;
-    IoMarkIrpPending(Irp);
-    IoQueueWorkItem(Context->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
-    return STATUS_PENDING;
+    // complete the request
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return Status;
 }
 
-
-
 NTSTATUS
 NTAPI
 PcCreateItemDispatch(
@@ -585,6 +526,7 @@ PcCreateItemDispatch(
     // sanity checks
     PC_ASSERT(SubDevice != NULL);
 
+
 #if KS_IMPLEMENTED
     Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader);
     if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED)