From: Johannes Anderwald Date: Wed, 4 Nov 2009 01:54:19 +0000 (+0000) Subject: [KS] X-Git-Tag: ReactOS-0.3.11~163 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=c5fab80345d032aaf74f00d4aacee5786c215a88 [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 svn path=/trunk/; revision=43945 --- diff --git a/reactos/drivers/ksfilter/ks/irp.c b/reactos/drivers/ksfilter/ks/irp.c index 5a1fb5b2209..4fdebe90302 100644 --- a/reactos/drivers/ksfilter/ks/irp.c +++ b/reactos/drivers/ksfilter/ks/irp.c @@ -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; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp b/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp index e69996421af..f201db292b8 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp @@ -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; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp index e4b4aaf68a8..38a6ae91ff5 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp @@ -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; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_topology.cpp b/reactos/drivers/wdm/audio/backpln/portcls/port_topology.cpp index 658876abeeb..2c80a430f22 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_topology.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_topology.cpp @@ -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)