- 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
This commit is contained in:
Johannes Anderwald 2009-11-04 01:54:19 +00:00
parent 420a4f5f4b
commit c5fab80345
4 changed files with 51 additions and 85 deletions

View file

@ -1240,6 +1240,7 @@ KsCancelIo(
PDRIVER_CANCEL OldDriverCancel; PDRIVER_CANCEL OldDriverCancel;
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PLIST_ENTRY Entry; PLIST_ENTRY Entry;
PLIST_ENTRY NextEntry;
PIRP Irp; PIRP Irp;
KIRQL OldLevel; KIRQL OldLevel;
@ -1253,6 +1254,9 @@ KsCancelIo(
/* get irp offset */ /* get irp offset */
Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry); Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
/* get next entry */
NextEntry = Entry->Flink;
/* set cancelled bit */ /* set cancelled bit */
Irp->Cancel = TRUE; Irp->Cancel = TRUE;
@ -1275,8 +1279,9 @@ KsCancelIo(
/* re-acquire spinlock */ /* re-acquire spinlock */
KeAcquireSpinLock(SpinLock, &OldLevel); KeAcquireSpinLock(SpinLock, &OldLevel);
} }
/* move on to next entry */ /* move on to next entry */
Entry = Entry->Flink; Entry = NextEntry;
} }
/* the irp has already been canceled */ /* the irp has already been canceled */
@ -1785,7 +1790,7 @@ KspCreate(
PKSIOBJECT_HEADER ObjectHeader; PKSIOBJECT_HEADER ObjectHeader;
NTSTATUS Status; NTSTATUS Status;
DPRINT("KS / CREATE\n"); DPRINT1("KS / CREATE\n");
/* get current stack location */ /* get current stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
/* get device extension */ /* get device extension */
@ -1838,7 +1843,6 @@ KspCreate(
return Status; return Status;
} }
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
/* set return status */ /* set return status */
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;

View file

@ -441,8 +441,20 @@ BOOL
NTAPI NTAPI
CIrpQueue::CancelBuffers() 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; m_StartStream = FALSE;
// done
return TRUE; return TRUE;
} }

View file

@ -268,7 +268,14 @@ PinWaveCyclicState(
{ {
// store new state // store new state
Pin->m_State = *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 // store result
Irp->IoStatus.Information = sizeof(KSSTATE); Irp->IoStatus.Information = sizeof(KSSTATE);
return Status; return Status;
@ -905,7 +912,8 @@ CPortPinWaveCyclic::Init(
} }
#endif #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)) if (!NT_SUCCESS(Status))
return Status; return Status;

View 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] = 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 NTSTATUS
NTAPI NTAPI
PcCreatePinDispatch( PcCreatePinDispatch(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
NTSTATUS Status;
IIrpTarget *Filter; IIrpTarget *Filter;
IIrpTarget *Pin;
PKSOBJECT_CREATE_ITEM CreateItem; PKSOBJECT_CREATE_ITEM CreateItem;
PPIN_WORKER_CONTEXT Context;
// access the create item // access the create item
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
@ -511,6 +463,7 @@ PcCreatePinDispatch(
// sanity checks // sanity checks
PC_ASSERT(Filter != NULL); PC_ASSERT(Filter != NULL);
PC_ASSERT_IRQL(PASSIVE_LEVEL);
#if KS_IMPLEMENTED #if KS_IMPLEMENTED
@ -524,45 +477,33 @@ PcCreatePinDispatch(
} }
#endif #endif
// new pins are instantiated at passive level, Status = Filter->NewIrpTarget(&Pin,
// so allocate a work item and context for it KSSTRING_Pin,
NULL,
NonPagedPool,
DeviceObject,
Irp,
NULL);
DPRINT("PcCreatePinDispatch Status %x\n", Status);
Context = (PPIN_WORKER_CONTEXT)AllocateItem(NonPagedPool, sizeof(PIN_WORKER_CONTEXT), TAG_PORTCLASS); if (NT_SUCCESS(Status))
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"); // create the dispatch object
FreeItem(Context, TAG_PORTCLASS); // FIXME need create item for clock
Irp->IoStatus.Information = 0; Status = NewDispatchObject(Irp, Pin, 0, NULL);
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; DPRINT("Pin %p\n", Pin);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INSUFFICIENT_RESOURCES;
} }
Context->Filter = Filter; DPRINT("CreatePinWorkerRoutine completing irp %p\n", Irp);
Context->Irp = Irp; // save status in irp
Irp->IoStatus.Status = Status;
DPRINT("Queueing IRP %p Irql %u\n", Irp, KeGetCurrentIrql());
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_PENDING; // complete the request
IoMarkIrpPending(Irp); IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoQueueWorkItem(Context->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context); return Status;
return STATUS_PENDING;
} }
NTSTATUS NTSTATUS
NTAPI NTAPI
PcCreateItemDispatch( PcCreateItemDispatch(
@ -585,6 +526,7 @@ PcCreateItemDispatch(
// sanity checks // sanity checks
PC_ASSERT(SubDevice != NULL); PC_ASSERT(SubDevice != NULL);
#if KS_IMPLEMENTED #if KS_IMPLEMENTED
Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader); Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader);
if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED) if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED)