Author: janderwald Date: Wed Nov 4 02:54:19 2009 New Revision: 43945 URL: http://svn.reactos.org/svn/reactos?rev=43945&view=rev Log: [KS] - 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
Modified: trunk/reactos/drivers/ksfilter/ks/irp.c trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.cpp Modified: trunk/reactos/drivers/ksfilter/ks/irp.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/irp.c?rev=43945&r1=43944&r2=43945&view=diff ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] Wed Nov 4 02:54:19 2009 @@ -1240,6 +1240,7 @@ PDRIVER_CANCEL OldDriverCancel; PIO_STACK_LOCATION IoStack; PLIST_ENTRY Entry; + PLIST_ENTRY NextEntry; PIRP Irp; KIRQL OldLevel; @@ -1253,6 +1254,9 @@ /* 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 @@ /* 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 @@ PKSIOBJECT_HEADER ObjectHeader; NTSTATUS Status; - DPRINT("KS / CREATE\n"); + DPRINT1("KS / CREATE\n"); /* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); /* get device extension */ @@ -1837,7 +1842,6 @@ } return Status; } - Irp->IoStatus.Information = 0; /* set return status */ Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp?rev=43945&r1=43944&r2=43945&view=diff ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp [iso-8859-1] Wed Nov 4 02:54:19 2009 @@ -441,8 +441,20 @@ 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; } Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp?rev=43945&r1=43944&r2=43945&view=diff ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp [iso-8859-1] Wed Nov 4 02:54:19 2009 @@ -268,7 +268,14 @@ { // 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 @@ } #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; Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.cpp?rev=43945&r1=43944&r2=43945&view=diff ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.cpp [iso-8859-1] Wed Nov 4 02:54:19 2009 @@ -54,13 +54,6 @@ friend PMINIPORTTOPOLOGY GetTopologyMiniport(PPORTTOPOLOGY Port); }; - -typedef struct -{ - PIRP Irp; - IIrpTarget *Filter; - PIO_WORKITEM WorkItem; -}PIN_WORKER_CONTEXT, *PPIN_WORKER_CONTEXT; static GUID InterfaceGuids[2] = { @@ -448,57 +441,16 @@ } -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 @@ // sanity checks PC_ASSERT(Filter != NULL); + PC_ASSERT_IRQL(PASSIVE_LEVEL); #if KS_IMPLEMENTED @@ -524,44 +477,32 @@ } #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; - } - - // allocate work item - Context->WorkItem = IoAllocateWorkItem(DeviceObject); - if (!Context->WorkItem) - { - 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; - } - - Context->Filter = Filter; - Context->Irp = Irp; - - DPRINT("Queueing IRP %p Irql %u\n", Irp, KeGetCurrentIrql()); + Status = Filter->NewIrpTarget(&Pin, + KSSTRING_Pin, + NULL, + NonPagedPool, + DeviceObject, + Irp, + NULL); + + DPRINT("PcCreatePinDispatch Status %x\n", Status); + + if (NT_SUCCESS(Status)) + { + // create the dispatch object + // FIXME need create item for clock + Status = NewDispatchObject(Irp, Pin, 0, NULL); + DPRINT("Pin %p\n", Pin); + } + + 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 @@ -584,6 +525,7 @@ // sanity checks PC_ASSERT(SubDevice != NULL); + #if KS_IMPLEMENTED Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader);