- 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;
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;

View 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;
}

View 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;

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] =
{
{
@ -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
Status = Filter->NewIrpTarget(&Pin,
KSSTRING_Pin,
NULL,
NonPagedPool,
DeviceObject,
Irp,
NULL);
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;
}
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)